JSONPath Sorgu Kılavuzu: JSON Verilerinde Nasıl Arama Yapılır
JSON web'in evrensel dili haline gelmiştir. API'ler JSON döndürür, yapılandırma dosyaları JSON kullanır, veritabanları JSON belgeleri depolar. Ancak JSON yapıları büyüdükçe ve daha derin iç içe geçtikçe, belirli değerleri bulmak giderek zorlaşır. İşte JSONPath burada devreye girer. JSONPath, XPath'in XML için yaptığı gibi, JSON belgelerindeki verileri gezinmek ve çıkarmak için özlü yol ifadeleri kullanmanıza olanak tanıyan bir sorgu dilidir. Bu kılavuz, temel sözdiziminden gelişmiş filtrelemeye kadar her şeyi ve hemen uygulayabileceğiniz pratik örnekleri kapsar.
JSONPath Nedir?
JSONPath, ilk olarak 2007 yılında Stefan Goessner tarafından önerilen bir JSON sorgu dilidir. CSS seçicilerin HTML öğelerini hedeflemesi veya XPath ifadelerinin XML düğümlerini bulması gibi, JSON belgelerinden düğüm seçmek için kompakt bir sözdizimi sağlar. JSON yapısını dolaşmak için döngüler ve koşullu mantık yazmak yerine, istenen veriye giden yolu tanımlayan bir ifade yazmanız yeterlidir.
JSONPath ifadeleri JSON belgesinin kök düğümünden başlar, istenen değere ulaşmak için nesneler ve diziler arasında gezinir. Dil, çoğu veri çıkarma ihtiyacı için yeterli olan joker karakterleri, özyinelemeli inişi, dizi dilimlemeyi ve filtre ifadelerini destekler.
Örnek JSON Belgesi
Bu kılavuzda, çalışma örneği olarak aşağıdaki JSON belgesini kullanacağız. Bu, orijinal JSONPath önerisindeki klasik örnektir ve ek verilerle genişletilmiştir:
{
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"category": "fiction",
"author": "J.R.R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
}
}JSONPath Sözdizimi Referansı
JSONPath, güçlü sorgular oluşturmak için birleşen küçük bir operatör seti kullanır. İşte tam sözdizimi referansı:
| Operatör | Açıklama | Örnek |
|---|---|---|
| $ | Belgenin kök düğümü | $ |
| . | Alt operatör (nesne özelliklerine erişir) | $.store |
| [] | Dizi indisi veya alt operatör | $.store.book[0] |
| [*] | Tüm dizi öğeleri için joker karakter | $.store.book[*] |
| .. | Özyinelemeli iniş (tüm seviyelerde ara) | $..author |
| .key | Adlandırılmış nesne özelliği | $.store.bicycle |
| ['key'] | Özellik erişimi için köşeli parantez gösterimi | $['store']['book'] |
| [start:end] | Dizi dilimleme (bitiş indisi hariç) | $.store.book[0:2] |
| [?()] | Filtre ifadesi | < 10)] |
| () | Script ifadesi (uygulamaya bağlı) | $.store.book[(@.length-1)] |
Temel JSONPath İfadeleri
Kök Düğüme ve Doğrudan Alt Öğelere Erişim
Dolar işareti $, JSON belgesinin kök düğümünü temsil eder. Buradan, nesne özelliklerine erişmek için nokta gösterimini, dizi indislerine erişmek için köşeli parantez gösterimini kullanırsınız.
| İfade | Sonuç |
|---|---|
| $ | Tüm JSON belgesi |
| $.store | store nesnesi (book dizisini ve bicycle nesnesini içerir) |
| $.store.bicycle | {"color": "red", "price": 19.95} |
| $.store.bicycle.color | "red" |
| $.store.book | Tüm book dizisi |
| $.store.book[0] | İlk kitap nesnesi |
| $.store.book[0].title | "Sayings of the Century" |
| $.store.book[3].author | "J.R.R. Tolkien" |
Köşeli Parantez Gösterimi
Köşeli parantez gösterimi, özellik adı özel karakterler, boşluklar içerdiğinde veya rakamla başladığında yararlı olan nokta gösterimine bir alternatiftir:
$.store['book'][0]['title']
$['store']['bicycle']['color']Köşeli parantez gösterimi ve nokta gösterimi, nesne özellikleri için birbirinin yerine kullanılabilir. Ancak, özellik adı dinamik olduğunda veya nokta gösteriminde geçersiz karakterler içerdiğinde köşeli parantez gösterimi zorunludur.
Joker Karakter Operatörleri
Joker karakter operatörü *, bir dizideki tüm öğelerle veya bir nesnedeki tüm özelliklerle eşleşir. Belirli anahtarları veya indisleri bilmeden bir seviyedeki tüm değerleri çıkarmak için son derece kullanışlıdır.
| İfade | Sonuç |
|---|---|
| $.store.* | store nesnesindeki tüm değerler (book dizisi ve bicycle nesnesi) |
| $.store.book[*] | Dizideki tüm kitaplar (dört book nesnesinin tümü) |
| $.store.book[*].author | Tüm yazar adları: ["Nigel Rees", "Evelyn Waugh", "Herman Melville", "J.R.R. Tolkien"] |
| $.store.*.price | bicycle'ın fiyatı ve book dizisi (tek tek kitapların fiyatı değil) |
Özyinelemeli İniş: Çift Nokta Operatörü
Çift nokta operatörü .. JSONPath'in en güçlü özelliklerinden biridir. Yalnızca doğrudan alt öğeleri değil, JSON ağacının her seviyesinde belirtilen anahtarı arar. Bunu tüm belge üzerinde derinlemesine bir arama olarak düşünün.
| İfade | Sonuç |
|---|---|
| $..author | Belgenin her yerindeki author değerleri |
| $..price | Tüm price değerleri: [8.95, 12.99, 8.99, 22.99, 19.95] |
| $..book[2] | Üçüncü kitap, özyinelemeli olarak bulunur |
| $..category | Tüm category değerleri: ["reference", "fiction", "fiction", "fiction"] |
Özyinelemeli iniş operatörü, istenen verinin tam yolunu bilmediğinizde veya aynı anahtar birden çok iç içe seviyede göründüğünde özellikle kullanışlıdır. Örneğin, bir API yanıtı çeşitli iç içe seviyelerde id alanları içeriyorsa, $..id tüm id'leri toplar.
Dizi Dilimleme
Dizi dilimleme, bir diziden bir dizi öğe seçmenize olanak tanır. Sözdizimi [başlangıç:bitiş], başlangıç indisinden bitiş indisine kadar (hariç) öğeleri seçer. Hem pozitif hem negatif indisler desteklenir.
| İfade | Sonuç |
|---|---|
| $.store.book[0:2] | İlk iki kitap (indis 0 ve 1) |
| $.store.book[1:3] | İkinci ve üçüncü kitaplar (indis 1 ve 2) |
| $.store.book[-1] | Son kitap (The Lord of the Rings) |
| $.store.book[-2:] | Son iki kitap |
| $.store.book[:2] | İlk iki kitap ([0:2] ile aynı) |
| $.store.book[2:] | Üçüncü kitap ve sonrası |
Dilimleme davranışının farklı JSONPath uygulamaları arasında biraz değişebileceğini unutmayın. Yukarıdaki sözdizimi, çoğu popüler kütüphane ve IETF RFC 9535 standardı tarafından kullanılan kuralı takip eder.
Filtre İfadeleri
Filtre ifadeleri, JSONPath'in gerçekten güçlü hale geldiği yerdir. Konum yerine koşullara göre öğe seçmenize olanak tanır. Filtre sözdizimi, her öğe için koşulun değerlendirildiği [?(koşul)] kullanır.
Karşılaştırma Operatörleri
JSONPath, filtre ifadelerinde aşağıdaki karşılaştırma operatörlerini destekler:
| Operatör | Anlam | Örnek |
|---|---|---|
| == | Eşittir | [?(@.category == "fiction")] |
| != | Eşit değildir | [?(@.category != "fiction")] |
| < | Küçüktür | < 10)] |
| <= | Küçük veya eşittir | <= 8.99)] |
| > | Büyüktür | [?(@.price > 15)] |
| >= | Büyük veya eşittir | [?(@.price >= 12.99)] |
| =~ | Regex eşleşmesi (kısmi uygulama) | [?(@.author =~ /Tolkien/i)] |
Pratik Filtre Örnekleri
Örnek belgemizi kullanarak, işte pratik filtre ifadeleri ve sonuçları:
Find all books cheaper than $10:
< 10)]"Sayings of the Century" ($8.95) ve "Moby Dick" ($8.99) kitaplarını döndürür.
Find all fiction books:
$.store.book[?(@.category == "fiction")]Üç kitap döndürür: "Sword of Honour", "Moby Dick" ve "The Lord of the Rings".
Find books with an ISBN:
$.store.book[?(@.isbn)]isbn özelliğine sahip kitapları döndürür: "Moby Dick" ve "The Lord of the Rings". Bunun nedeni, filtrenin özelliğin var olup olmadığını kontrol etmesidir.
Find the most expensive book:
$.store.book[?(@.price > 20)]"The Lord of the Rings" ($22.99) kitabını döndürür.
Filtrelerde Mantıksal Operatörler
Koşulları mantıksal operatörlerle birleştirebilirsiniz:
< 10 && @.category == "fiction")]
$.store.book[?(@.price > 15 || @.category == "reference")]İlk ifade, 10 doların altındaki kurgu kitaplarını bulur (yalnızca "Moby Dick"). İkincisi, 15 doların üzerinde veya referans kategorisindeki kitapları bulur ("Sayings of the Century" ve "The Lord of the Rings" döndürür).
JSONPath ve XPath
JSONPath açıkça XPath'i model almıştır ve iki dil kavramsal olarak birçok benzerliğe sahiptir. XML işlemeye aşinaysanız, bu ilişkiyi anlamak yardımcı olur.
| Özellik | JSONPath | XPath |
|---|---|---|
| Kök sembolü | $ | / |
| Alt öğe erişimi | .key veya ['key'] | /element |
| Dizi indisi | [0] | [1] (1'den başlar) |
| Joker karakter | * | * |
| Özyinelemeli iniş | .. | // |
| Filtreleme | [?(condition)] | [condition] |
| Öznitelik | Uygulanamaz (JSON'da öznitelik yok) | @attr |
| Geçerli düğüm | @ (filtrelerde) | . veya current() |
| Üst öğe | Desteklenmez | .. |
| Eksen | Desteklenmez | 13 eksen (ancestor, following vb.) |
| Veri modeli | Nesneler ve diziler | Öğeler, öznitelikler, metin düğümleri |
Temel fark, XPath'in öğeler, öznitelikler, metin düğümleri, ad alanları ve işleme talimatlarından oluşan zengin bir ağaç modeli üzerinde çalışmasıdır. JSONPath, nesneler (anahtar-değer eşlemeleri) ve diziler (sıralı listeler) gibi daha basit bir model üzerinde çalışır. Bu basitlik JSONPath'i öğrenmeyi kolaylaştırır ancak karmaşık sorgularda XPath kadar ifade gücüne sahip değildir.
JSONPath Uygulaması
API Testi
JSONPath, API testi için vazgeçilmezdir. Bir API'ye istek gönderdiğinizde ve büyük bir JSON yanıtı aldığınızda, JSONPath tüm yapıyı manuel olarak dolaşmadan belirli değerleri doğrulamanıza olanak tanır. Çoğu API test aracı JSONPath'i doğal olarak destekler.
Örneğin, bir testte ilk kitabın fiyatının 10 doların altında olduğunu doğrulayabilirsiniz:
// Using a JSONPath assertion in testing
response.jsonPath().get("store.book[0].price").should(equals(8.95));
// Find all books by a specific author
response.jsonPath().get("store.book[?(@.author == 'Herman Melville')].title");
// Returns: ["Moby Dick"]Veri Dönüşümü
Farklı veri formatları kullanan sistemleri entegre ederken, JSONPath belirli alanları çıkarmaya ve dönüştürmeye yardımcı olur. Karmaşık dolaşma kodu yazmadan bir JSON yapısından değerleri çıkarabilir ve başka birine eşleyebilirsiniz.
Yapılandırma Yönetimi
Karmaşık yapılandırma dosyaları genellikle derin iç içe JSON içerir. JSONPath, tüm yapıyı yüklemeden ve ayrıştırmadan belirli yapılandırma değerlerini sorgulamanıza olanak tanır. jq gibi araçlar, komut satırı ardışık düzenlerinde JSON işlemek için JSONPath benzeri sözdizimi kullanır.
İzleme ve Uyarı
Gözlemlenebilirlik sistemlerinde, JSONPath sorguları JSON formatlı günlüklerden ve API yanıtlarından metrikler çıkarabilir. JSONPath sorgusu eşik değerini aşan bir değer döndürdüğünde tetiklenen uyarılar ayarlayabilirsiniz.
JSONPath Uygulamaları
JSONPath neredeyse her programlama dilinde mevcuttur. İşte en popüler kütüphaneler:
| Dil | Kütüphane | Kurulum |
|---|---|---|
| JavaScript | jsonpath-plus | npm install jsonpath-plus |
| Python | jsonpath-ng | pip install jsonpath-ng |
| Java | JsonPath (Jayway) | Maven: com.jayway.jsonpath |
| C# | Json.NET (Newtonsoft) | NuGet: Newtonsoft.Json |
| Go | gjson | go get github.com/tidwall/gjson |
| PHP | jsonpath | composer require softcreatr/jsonpath |
| Ruby | jsonpath | gem install jsonpath |
JavaScript Örneği
< 10)]',
json: data
});
// Returns books with price < 10
Python Example
from jsonpath_ng import parse
data = { /* our sample JSON */ }
# Find all authors
author_expr = parse('$..author')
authors = [match.value for match in author_expr.find(data)]
# ["Nigel Rees", "Evelyn Waugh", "Herman Melville", "J.R.R. Tolkien"]
# Find cheap books
cheap_expr = parse('$.store.book[?(@.price < 10)]')
cheap_books = [match.value for match in cheap_expr.find(data)]
Common Pitfalls and Tips
- Zero-based vs one-based indexing: JSONPath uses zero-based indexing (the first element is [0]), while XPath uses one-based indexing (the first element is [1]). This is a common source of off-by-one errors.
- Implementation differences: Before the IETF standard (RFC 9535), JSONPath implementations varied in their handling of edge cases like empty results, null values, and filter syntax. Always test your expressions with the specific library you are using.
- Filter performance: Recursive descent with filters (
$..book[?(@.price < 10)]) can be slow on large documents because it must traverse the entire tree. For performance-critical applications, use more specific paths when possible. - Case sensitivity: JSONPath is case-sensitive.
$.Storewill not match$.store. This is consistent with JSON's case-sensitive nature. - Sıfır tabanlı ve bir tabanlı indeksleme: JSONPath sıfır tabanlı indeksleme kullanır (ilk öğe [0]'dır), XPath ise bir tabanlı indeksleme kullanır (ilk öğe [1]'dir). Bu, bir eksik hatalarının yaygın bir kaynağıdır.
- Uygulama farklılıkları: IETF standardından (RFC 9535) önce, JSONPath uygulamaları boş sonuçlar, null değerler ve filtre sözdizimi gibi kenar durumlarını işlerken farklılık gösteriyordu. Her zaman ifadelerinizi kullandığınız belirli kütüphane ile test edin.
Yaygın Tuzaklar ve İpuçları
2024 yılında IETF, JSONPath'i resmi olarak standartlaştıran RFC 9535'i yayınladı. Spesifikasyon, uygulamalar arasında var olan birçok belirsizliği ve tutarsızlığı çözdü. Standardın temel yönleri şunları içerir:
- < 10)]) tüm ağacı dolaşması gerektiğinden büyük belgelerde yavaş olabilir. Performans açısından kritik uygulamalar için mümkün olduğunca daha spesifik yollar kullanın.
- Büyük/küçük harf duyarlılığı: JSONPath büyük/küçük harfe duyarlıdır. $.Store, $.store ile eşleşmez. Bu, JSON'ın büyük/küçük harfe duyarlı yapısıyla tutarlıdır.
- Özel karakterleri kaçırma: Anahtar adları nokta veya köşeli parantez içeriyorsa, tırnaklı köşeli parantez gösterimi kullanmalısınız: $.key.with.dots yerine $['key.with.dots'].
- Üst öğeye gezinme yok: XPath'ten farklı olarak, JSONPath üst düğüme gidemez. XPath'in .. (üst eksen) eşdeğeri yoktur. JSONPath'teki .. özyinelemeli iniş anlamına gelir, üst öğe değil.
Yeni bir projeye başlıyorsanız, maksimum uyumluluk ve öngörülebilir davranış için RFC 9535'i uygulayan kütüphaneleri tercih edin.
JSON verilerini hızlıca sorgulamanız mı gerekiyor? İfadeleri kendi JSON belgelerinize karşı gerçek zamanlı olarak değerlendiren ücretsiz çevrimiçi JSONPath test aracımızı deneyin.
JSONPath Bulucuyu DeneIETF Standardı: RFC 9535
Python Örneği
JSONPath, XPath'in XML için olduğu gibi JSON için bir sorgu dilidir. JSON belgelerindeki belirli değerleri gezinmek ve çıkarmak için yol ifadeleri kullanır. $.store.book[0].title gibi bir JSONPath ifadesi, özel ayrıştırma kodu yazmadan karmaşık iç içe JSON yapılarında verileri hassas bir şekilde konumlandırmanıza olanak tanır.
JSONPath nedir?
JSONPath, JSON'ın nesne ve dizi yapısı için tasarlanmıştır, XPath ise XML'in öğe ve öznitelik ağacı için tasarlanmıştır. JSONPath kök düğüm olarak $, nesnelere erişmek için nokta gösterimi, dizilere erişmek için köşeli parantez gösterimi kullanır. XPath yol ayırıcı olarak /, özniteliklere erişmek için @ kullanır. JSONPath daha basittir ancak XPath kadar zengin özelliklere sahip değildir.
JSONPath XPath'ten nasıl farklıdır?
JSONPath'teki çift nokta (..) özyinelemeli iniş operatörüdür. Yalnızca doğrudan alt öğeleri değil, JSON yapısının tüm seviyelerinde adlandırılmış anahtarı arar. Örneğin, $..author, ne kadar derine gömülü olursa olsun, belgenin herhangi bir yerindeki tüm author anahtarlarını bulur.
JSONPath'te çift nokta (..) ne anlama gelir?
<, ><=, >< 10)] 10 doların altındaki tüm kitapları bulur.
JSONPath koşullara göre veri filtreleyebilir mi?
JSONPath ilk olarak 2007 yılında Stefan Goessner tarafından resmi bir spesifikasyon olmadan önerildi ve uygulamalar arasında farklılıklara yol açtı. 2024'te IETF, JSONPath'i resmi olarak standartlaştıran RFC 9535'i yayınladı. Modern uygulamalar bu standarda yakınsıyor, ancak bazı eski kütüphaneler hala küçük sözdizimi farklılıklarına sahip olabilir.