มีเทียบเท่า JSON ของ XQuery / XPath?


221

เมื่อค้นหารายการในอาร์เรย์และแฮชที่ซับซ้อนของ JSON เช่น:

[
    { "id": 1, "name": "One", "objects": [
        { "id": 1, "name": "Response 1", "objects": [
            // etc.
        }]
    }
]

มีภาษาสืบค้นบางประเภทที่ฉันสามารถใช้ค้นหารายการได้in [0].objects where id = 3หรือไม่


ไม่เว้นแต่คุณจะทำ ปล่อยให้การสืบค้นไปยังเซิร์ฟเวอร์และใช้ REST เพื่อรับเฉพาะข้อมูลที่คุณต้องการ
zzzzBov

5
+1 ความคิดที่ดี พรุ่งนี้จะเขียนสิ่งนี้ ...

2
ไม่ XPath แต่ฉันได้พบ JLinq สวยดี (ซึ่งทำให้รหัสที่จะอ่านเหมือนin(...).where(...).select(...)): hugoware.net/Projects/jLinq
pimvdb

4
สิ่งนี้น่าหงุดหงิดเพราะมีห้องสมุดจำนวนมากอยู่ที่นั่น แต่ไม่มีอะไรเข้าใกล้มาตรฐานที่ยอมรับกันโดยทั่วไป เรามีห้องสมุดที่ใช้โดยบุคคลที่สามดังนั้นเราจึงจำเป็นต้องจัดหาภาษาแบบสอบถามที่เป็นที่รู้จักและใช้กันอย่างแพร่หลาย
David Thielen

1
แน่นอนว่าคุณสามารถใช้ jsel - github.com/dragonworx/jsel - เนื่องจากคุณมีตัวแปรdataที่มีวัตถุ JSON ของคุณคุณจะเขียน: jsel(data).select("//*[@id=3]")และมันจะคืนค่าวัตถุที่มีรหัสคีย์ด้วย 3
Ali

คำตอบ:


122

Yup ก็เรียกว่าJSONPath แหล่งที่มาคือตอนนี้บนGitHub

นอกจากนี้ยังรวมอยู่ในDOJO


3
คำตอบของ Brian แนะนำว่าควรใช้โมดูล jsonQuery แทนโมดูล jsonPath ใน dojo
hugomg

5
นี่มันแข็งแค่ไหน? และฉันไม่สามารถหารุ่น Java หรือ C # ซึ่งเป็นตัวจัดการข้อตกลงสำหรับเรา
David Thielen

2
เว็บไซต์ที่เชื่อมโยงที่นี่มีไว้สำหรับ Javascript และ PHP หากคุณต้องการใช้งาน Java มีอยู่ที่นี่: code.google.com/p/json-path
Matthias Ronge

2
ฉันควรพูดถึงว่า JSONPath ไม่ได้ขึ้นอยู่กับ semantic ทางการ XPath JSONiq อาจเป็นตัวเลือกที่ดีกว่า
wcandillon

1
@Paramaeleon มันใช้งานได้ดี โครงการย้ายไปที่ GitHubแล้ว ไมค์อาจต้องการเพิ่มคำตอบนี้เนื่องจากผู้คนมักแสดงความคิดเห็นเกี่ยวกับเรื่องนี้
แฟรงคลินหยู

21

ผมคิดว่า JSONQuery เป็น superset ของ JSONPath และทำให้แทนที่มันในโดโจ จากนั้นก็มีRQLด้วย

จากเอกสาร Dojo:

JSONQuery เป็นเวอร์ชันเพิ่มเติมของ JSONPath ที่มีคุณสมบัติเพิ่มเติมเพื่อความปลอดภัยความสะดวกในการใช้งานและชุดเครื่องมือสืบค้นข้อมูลที่ครอบคลุมซึ่งรวมถึงการกรองการค้นหาแบบวนซ้ำการเรียงลำดับการแม็ปการเลือกช่วงและการแสดงความยืดหยุ่นด้วยการเปรียบเทียบสตริงอักขระตัวแทน

JSONselectมีอีกจุดหนึ่งของมุมมองในคำถาม (เลือก CSS เหมือนมากกว่า XPath) และมีการใช้งานจาวาสคริ


4
ลิงก์ Github JSONQuery ดูเหมือนว่าจะตาย JSONSelect ยังมีเวอร์ชัน JavaScript ในขณะนี้
Henrik Aasted Sørensen

19

ทางเลือกอื่น ๆ ที่ฉันรับรู้

  1. ข้อกำหนดJSONiqซึ่งระบุสองประเภทย่อยของภาษา: หนึ่งรายการที่ซ่อนรายละเอียด XML และจัดเตรียมไวยากรณ์เหมือน JS และอีกประเภทหนึ่งที่เสริมสร้างไวยากรณ์ XQuery ด้วยตัวสร้าง JSON และเช่นนั้น Zorbaดำเนินการ JSONiq
  2. Coronaซึ่งสร้างจากด้านบนของ MarkLogic มีส่วนต่อประสาน REST สำหรับจัดเก็บจัดการและค้นหาเนื้อหา XML, JSON, ข้อความและไบนารี
  3. MarkLogic 6 และใหม่กว่าจัดเตรียมอินเตอร์เฟส REST ที่คล้ายกันเป็น Corona นอกกรอบ
  4. MarkLogic 8 และใหม่กว่ารองรับ JSON ในสภาพแวดล้อมทั้ง XQuery และ JavaScript ฝั่งเซิร์ฟเวอร์ คุณสามารถใช้ XPath กับมันได้

HTH


3
ขณะนี้มีการใช้งาน JSONiq: Zorba 2.6 สนับสนุนอย่างเป็นทางการ
Ghislain Fourny

หมายเหตุ: MarkLogic เก็บ JSON โดยเป็นรุ่น 8 และอนุญาตให้ใช้ XPath กับมันโดยตรง
grtjn

18

เพื่อสรุปตัวเลือกปัจจุบันสำหรับการสำรวจ / กรองข้อมูล JSON และให้ตัวอย่างไวยากรณ์ ...

  • JSPath
    .automobiles{.maker === "Honda" && .year > 2009}.model

  • json: select () (ได้แรงบันดาลใจมาจากตัวเลือก CSS)
    .automobiles .maker:val("Honda") .model

  • JSONPath (แรงบันดาลใจจาก XPath)
    $.automobiles[?(@.maker='Honda')].model

ฉันคิดว่า JSPath ดูดีที่สุดดังนั้นฉันจะลองและรวมเข้ากับแอป AngularJS + CakePHP ของฉัน

(ตอนแรกฉันโพสต์คำตอบนี้ในหัวข้ออื่นแต่คิดว่ามันจะมีประโยชน์ที่นี่เช่นกัน)


ข้อสรุปและตัวอย่างที่ยอดเยี่ยมรวมถึงการกล่าวถึงแรงบันดาลใจที่พบในตัวเลือก CSS หรือ XPath
Jochem Schulenklopper

13

ลองใช้JSPath

JSPath เป็นภาษาเฉพาะโดเมน (DSL) ที่ช่วยให้คุณนำทางและค้นหาข้อมูลภายในเอกสาร JSON ของคุณ การใช้ JSPath คุณสามารถเลือกรายการของ JSON เพื่อดึงข้อมูลที่มีอยู่

JSPath สำหรับ JSON เหมือน XPath สำหรับ XML

มันถูกปรับให้เหมาะสมอย่างมากทั้งสำหรับ Node.js และเบราว์เซอร์ที่ทันสมัย


9

XQuery สามารถใช้เพื่อเคียวรี JSON โดยที่ตัวประมวลผลนั้นสนับสนุน JSON นี่คือตัวอย่างที่ตรงไปตรงมาว่า BaseX สามารถใช้เพื่อค้นหาวัตถุที่มี "id" = 1:

json:parse('[
    { "id": 1, "name": "One", "objects": [
        { "id": 1, "name": "Response 1", "objects": [ "etc." ] }
    ]}
]')//value[.//id = 1]

(6 ปีขึ้นไป) แซ็กซอนจะเรียกใช้ XQuery 3.1 ซึ่งจะสอบถาม JSON ประสบการณ์แซกซอนของฉันกำลังใช้ไฟล์ jar ที่รันโดย java มีโมดูลโหนดชื่อ saxon-java แต่ฉันไม่แน่ใจว่าวิธีการทำงาน w / json และยังมีสิ่งใหม่จากแซกโซนิกาชื่อแซ็กซอน - เจ
charles ross

9

มีภาษาของแบบสอบถามบ้างไหม ...

jqกำหนดภาษาJ SON q uery ที่คล้ายกับ JSONPath - ดู https://github.com/stedolan/jq/wiki/For-JSONPath-users

... [ใด] ฉันสามารถใช้เพื่อค้นหารายการใน [0] .objects โดยที่ id = 3?

ฉันจะถือว่าวิธีนี้: ค้นหาวัตถุ JSON ทั้งหมดภายใต้คีย์ที่ระบุด้วย id == 3 ไม่ว่าวัตถุจะอยู่ที่ใด แบบสอบถาม jq ที่สอดคล้องกันจะเป็น:

.[0].objects | .. | objects | select(.id==3)

ที่ไหน "|" เป็นตัวดำเนินการไปป์ (ในคำสั่งเชลล์ท่อ) และตำแหน่ง ".. | วัตถุ" สอดคล้องกับ "ไม่ว่าวัตถุจะอยู่ที่ไหน"

พื้นฐานของ jq นั้นชัดเจนหรือง่ายหรืออย่างน้อยและส่วนที่เหลือนั้นง่ายต่อการรับถ้าคุณคุ้นเคยกับท่อ command-shell คำถามที่พบบ่อย jq มีตัวชี้ไปยังบทเรียนและไม่ชอบ

jq ก็เหมือนกับ SQL ที่สนับสนุนการทำงานของ CRUD แม้ว่าตัวประมวลผล jq จะไม่เขียนทับอินพุตของมัน jq ยังสามารถจัดการสตรีมของเอนทิตี JSON

อีกสองเกณฑ์ที่คุณอาจต้องการพิจารณาในการประเมินภาษาคิวรีที่เน้น JSON คือ:

  • รองรับการแสดงผลปกติหรือไม่ (jq 1.5 ได้รับการสนับสนุนอย่างครอบคลุมสำหรับ PCRE regex)
  • ทัวริงสมบูรณ์ไหม (ครับ)

8

Defiant.jsดูเจ๋งมากนี่เป็นตัวอย่างง่ายๆ:

var obj = {
        "car": [
            {"id": 10, "color": "silver", "name": "Volvo"},
            {"id": 11, "color": "red",    "name": "Saab"},
            {"id": 12, "color": "red",    "name": "Peugeot"},
            {"id": 13, "color": "yellow", "name": "Porsche"}
        ],
        "bike": [
            {"id": 20, "color": "black", "name": "Cannondale"},
            {"id": 21, "color": "red",   "name": "Shimano"}
        ]
    },
    search = JSON.search(obj, '//car[color="yellow"]/name');

console.log( search );
// ["Porsche"]

var reds = JSON.search(obj, '//*[color="red"]');

for (var i=0; i<reds.length; i++) {
    console.log( reds[i].name );
}
// Saab
// Peugeot
// Shimano

แต่น่าเสียดายที่ไม่ได้เผยแพร่บน NPM ในขณะนี้และต้องมีการติดตั้งด้วยตนเอง ...
แอนดรูเหมา


7

Jsel XPath จริง อนุญาตให้คุณสร้างนิพจน์ XPath เพื่อค้นหาข้อมูล JavaScript ประเภทใด ๆ ไม่ใช่แค่วัตถุ (สตริงด้วย)

คุณสามารถสร้าง schema ที่กำหนดเองและการแมปเพื่อให้คุณควบคุมวิธีการที่ข้อมูลของคุณสามารถเดินได้โดยเครื่องมือ XPath สคีมาเป็นวิธีการกำหนดวิธีกำหนดองค์ประกอบลูกคุณลักษณะและค่าโหนดในข้อมูลของคุณ จากนั้นคุณสามารถสร้างการแสดงออกของคุณเองเพื่อให้เหมาะกับ

ให้คุณมีตัวแปรที่เรียกว่าdataที่มี JSON จากคำถามคุณสามารถใช้ jsel เพื่อเขียน:

jsel(data).select("//*[@id=3]")

สิ่งนี้จะส่งคืนโหนดใด ๆ ที่มีidแอ็ตทริบิวต์ที่ 3 คุณลักษณะคือค่าดั้งเดิม (สตริง, จำนวน, วันที่, regex) ภายในวัตถุ


6

ObjectPathเป็นภาษาแบบสอบถามคล้ายกับ XPath หรือ JSONPath แต่มีประสิทธิภาพมากขึ้นด้วยการคำนวณทางคณิตศาสตร์แบบฝังกลไกการเปรียบเทียบและฟังก์ชั่นในตัว ดูไวยากรณ์:

ค้นหาในร้านรองเท้าทั้งหมดที่มีสีแดงและราคาน้อยกว่า 50

$ .. รองเท้า. * [สีคือ "สีแดง" และราคา <50]


ฉันชอบตัวอย่างแรกบนเว็บไซต์และเป็นเรื่องดีที่ ObjectPath สามารถทำงานในโหมดการโต้ตอบเชลล์เหมือน แต่สิ่งที่ฉันกำลังมองหาคือการใช้ ObjectPath ในสคริปต์ Python คุณสามารถชี้ให้ฉันเป็นตัวอย่างที่แสดงวิธีการใช้ ObjectPath เป็นห้องสมุดได้หรือไม่? ฉันไม่พบสิ่งใดบนเว็บไซต์
piokuc

โปรดดูส่วนที่เกี่ยวกับการใช้งานหลามบนGitHub เราจะเพิ่มสิ่งนี้ลงในเว็บไซต์ซึ่งหาได้ยากในตอนนี้ หากคุณต้องการความช่วยเหลือเพิ่มเติมใด ๆ คุณสามารถโพสต์คำถามบนกลุ่ม Google
Ela Bednarek

ขอบคุณ Ela ตัวอย่างที่เพิ่มในหน้า Github นั้นเป็นสิ่งที่ต้องการ
piokuc

4

@Naftule - ด้วย "defiant.js" คุณสามารถสืบค้นโครงสร้าง JSON ด้วยนิพจน์ XPath ลองใช้ตัวประเมินผลนี้เพื่อดูว่ามันทำงานอย่างไร:

http://www.defiantjs.com/#xpath_evaluator

ซึ่งแตกต่างจาก JSONPath "defiant.js" มอบการสนับสนุนเต็มรูปแบบของไวยากรณ์แบบสอบถาม - ของ XPath บนโครงสร้าง JSON

ซอร์สโค้ดของ defiant.js อยู่ที่นี่:
https://github.com/hbi99/defiant.js


3

ดูเหมือนว่าJMESPathจะได้รับความนิยมอย่างมากในวันนี้ (ตั้งแต่ปี 2563) และแก้ไขปัญหาต่างๆเกี่ยวกับ JSONPath มีให้บริการในหลายภาษา


1

หากคุณเป็นเหมือนฉันและคุณเพียงต้องการค้นหาเส้นทางตาม แต่ไม่สนใจ XPath จริง ๆ ของ lodash _.get()สามารถทำงานได้ ตัวอย่างจาก lodash docs:

var object = { 'a': [{ 'b': { 'c': 3 } }] };

_.get(object, 'a[0].b.c');
// → 3

_.get(object, ['a', '0', 'b', 'c']);
// → 3

_.get(object, 'a.b.c', 'default');
// → 'default'

น่าเสียดายที่ฟังก์ชันสามารถส่งคืนผลลัพธ์เดียวเท่านั้น แต่ไม่สนับสนุนการดึงข้อมูลรายการที่ตรงกันซึ่งเป็นที่ที่ห้องสมุดอื่น ๆ ฉาย
Simon East

0

ลองใช้งาน - https://github.com/satyapaul/jpath/blob/master/JSONDataReader.java

มันใช้งานง่ายมากบนบรรทัด xpath ที่คล้ายกันสำหรับ xml มันเป็นชื่อ jpath


1
คำถามนี้ถูกติดแท็กjavascriptแต่ดูเหมือนว่าห้องสมุดนี้จะเป็นจาวา
tripleee

มันมีรุ่น Javascript ด้วย - github.com/satyapaul/jpath/blob/master/jpath.jsนี่คือเขาคอมไพล์โฮมเพจสำหรับโครงการ - github.com/satyapaul/jpath
Satyajit Paul
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.