Có JSON tương đương với XQuery / XPath không?


221

Khi tìm kiếm các mục trong mảng JSON và băm phức tạp, như:

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

Có một số loại ngôn ngữ truy vấn tôi có thể sử dụng để tìm một mục in [0].objects where id = 3?


trừ khi bạn làm cho một. Để lại truy vấn đến máy chủ và sử dụng REST để chỉ nhận dữ liệu bạn cần.
zzzzBov

5
+1 ý tưởng hay. Gonna viết cái này vào ngày mai

2
Không phải XPath, nhưng tôi đã thấy JLinq khá tốt (giúp tạo mã để đọc như thế in(...).where(...).select(...)): hugoware.net/Projects/jLinq .
pimvdb

4
Điều này thật khó chịu vì có rất nhiều thư viện ngoài kia, nhưng không có gì tiếp cận với một tiêu chuẩn thường được chấp nhận. Chúng tôi có một thư viện được sử dụng bởi các bên thứ 3 vì vậy chúng tôi cần cung cấp một ngôn ngữ truy vấn được biết đến và sử dụng rộng rãi.
David Thielen

1
Chắc chắn, bạn có thể sử dụng jsel - github.com/dragonworx/jsel - nếu bạn có một biến datachứa đối tượng JSON của mình, bạn sẽ viết: jsel(data).select("//*[@id=3]")và nó sẽ trả về đối tượng chứa khóa id với 3.
Ali

Câu trả lời:


122

Phải , nó được gọi là JSONPath . Nguồn hiện có trên GitHub .

Nó cũng được tích hợp vào DOJO .


3
Câu trả lời của Brian cho thấy nên sử dụng mô đun jsonQuery thay vì mô đun jsonPath trong võ đường.
hugomg

5
Làm thế nào vững chắc là điều này? Và tôi không thể tìm thấy phiên bản Java hoặc C #, một kẻ giết người đối phó với chúng tôi.
David Thielen

2
Trang web được liên kết ở đây cung cấp cho Javascript và PHP. Nếu bạn cần triển khai Java, có một cái ở đây: code.google.com/p/json-path
Matthias Rrid

2
Tôi nên đề cập rằng JSONPath không dựa trên ngữ nghĩa chính thức XPath. JSONiq có thể là một lựa chọn tốt hơn.
wcandillon

1
@Paramaeleon Điều đó làm việc tuyệt vời. Nhân tiện, dự án đã được chuyển sang GitHub . Mike có thể muốn thêm điều này vào câu trả lời, vì mọi người cứ bình luận về điều này.
Franklin Yu

21

Tôi nghĩ JSONQuery là một siêu bộ của JSONPath và do đó thay thế nó trong võ đường . Rồi còn có RQL .

Từ tài liệu Dojo:

JSONQuery là phiên bản mở rộng của JSONPath với các tính năng bổ sung để bảo mật, dễ sử dụng và một bộ công cụ truy vấn dữ liệu toàn diện bao gồm lọc, tìm kiếm đệ quy, sắp xếp, ánh xạ, lựa chọn phạm vi và biểu thức linh hoạt với so sánh chuỗi ký tự đại diện và các toán tử khác nhau.

JSONselect có một quan điểm khác về câu hỏi (giống như bộ chọn CSS, thay vì XPath) và có triển khai JavaScript .


4
Liên kết JSONQuery của github dường như đã chết. Bây giờ, JSONSelect cũng có phiên bản JavaScript.
Henrik Aast SøDRen

19

Các lựa chọn thay thế khác mà tôi biết là

  1. Đặc tả JSONiq , chỉ định hai kiểu ngôn ngữ: một kiểu ẩn các chi tiết XML và cung cấp cú pháp giống như JS và một kiểu làm phong phú cú pháp XQuery bằng các hàm tạo JSON và như vậy. Zorba triển khai JSONiq.
  2. Corona , được xây dựng trên đỉnh MarkLogic cung cấp giao diện REST để lưu trữ, quản lý và tìm kiếm nội dung XML, JSON, Văn bản và nhị phân.
  3. MarkLogic 6 và sau đó cung cấp giao diện REST tương tự như Corona ngoài hộp.
  4. MarkLogic 8 trở lên hỗ trợ JSON nguyên bản trong cả môi trường JavaScript phía XQuery và máy chủ của họ. Bạn có thể áp dụng XPath trên nó.

HTH.


3
Hiện tại đã có một triển khai JSONiq: Zorba 2.6 chính thức hỗ trợ nó.
Ghislain Fourny

Lưu ý: MarkLogic lưu trữ JSON nguyên bản kể từ phiên bản 8 và cho phép áp dụng XPath trực tiếp trên nó.
grtjn

18

Để tóm tắt một số tùy chọn hiện tại để duyệt / lọc dữ liệu JSON và cung cấp một số ví dụ cú pháp ...

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

  • json: select () (lấy cảm hứng nhiều hơn từ các bộ chọn CSS)
    .automobiles .maker:val("Honda") .model

  • JSONPath (lấy cảm hứng từ XPath)
    $.automobiles[?(@.maker='Honda')].model

Tôi nghĩ rằng JSPath trông đẹp nhất, vì vậy tôi sẽ thử và tích hợp nó với ứng dụng AngularJS + CakePHP của tôi.

(Ban đầu tôi đã đăng câu trả lời này trong một chủ đề khác nhưng cũng nghĩ rằng nó cũng hữu ích ở đây.)


Tóm tắt và ví dụ tuyệt vời, cũng vì đề cập đến cảm hứng được tìm thấy trong các bộ chọn CSS hoặc XPath.
Joool Schulenklopper 17/10/18

13

Hãy thử sử dụng JSPath

JSPath là ngôn ngữ dành riêng cho miền (DSL) cho phép bạn điều hướng và tìm dữ liệu trong các tài liệu JSON của mình. Sử dụng JSPath, bạn có thể chọn các mục của JSON để lấy dữ liệu chứa trong đó.

JSPath cho JSON như XPath cho XML.

Nó được tối ưu hóa mạnh mẽ cho cả Node.js và các trình duyệt hiện đại.


9

XQuery có thể được sử dụng để truy vấn JSON, miễn là bộ xử lý cung cấp hỗ trợ JSON. Đây là một ví dụ đơn giản về cách BaseX có thể được sử dụng để tìm các đối tượng có "id" = 1:

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

(6 năm trở đi) Saxon sẽ chạy XQuery 3.1, truy vấn JSON. Kinh nghiệm Saxon của tôi là sử dụng tệp jar được chạy bởi java. Có một mô-đun nút có tên saxon-java nhưng tôi không chắc cách thức hoạt động của w / json. Và có một điều mới từ Saxonica được gọi là Saxon-JS.
charles ross

9

Có một số loại ngôn ngữ truy vấn ...

jq định nghĩa một ngôn ngữ J SON q uery rất giống với JSONPath - xem https://github.com/stedolan/jq/wiki/For-JSONPath-users

... [Mà] Tôi có thể sử dụng để tìm một mục trong [0] .objects trong đó id = 3?

Tôi sẽ giả sử điều này có nghĩa là: tìm tất cả các đối tượng JSON dưới khóa được chỉ định với id == 3, bất kể đối tượng có thể ở đâu. Một truy vấn jq tương ứng sẽ là:

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

trong đó "|" là toán tử đường ống (như trong các ống vỏ lệnh) và trong đó đoạn ".. | đối tượng" tương ứng với "bất kể đối tượng có thể ở đâu".

Những điều cơ bản của jq phần lớn là rõ ràng hoặc trực quan hoặc ít nhất là khá đơn giản, và hầu hết phần còn lại rất dễ nhận nếu bạn hoàn toàn quen thuộc với các ống vỏ lệnh. Câu hỏi thường gặp jq có con trỏ đến hướng dẫn và tương tự.

jq cũng giống như SQL ở chỗ nó hỗ trợ các hoạt động CRUD, mặc dù bộ xử lý jq không bao giờ ghi đè lên đầu vào của nó. jq cũng có thể xử lý các luồng của các thực thể JSON.

Hai tiêu chí khác bạn có thể muốn xem xét khi đánh giá ngôn ngữ truy vấn hướng JSON là:

  • nó có hỗ trợ các biểu thức chính quy không? (jq 1.5 có hỗ trợ toàn diện cho regex PCRE)
  • Turing đã hoàn thành chưa? (Vâng)

8

Defiant.js trông cũng khá tuyệt, đây là một ví dụ đơn giản:

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

Thật không may, không được công bố vào lúc npm tại thời điểm này và yêu cầu cài đặt thủ công ...
Andrew Mao


7

Jsel là tuyệt vời và dựa trên một công cụ XPath thực sự. Nó cho phép bạn tạo các biểu thức XPath để tìm bất kỳ loại dữ liệu JavaScript nào, không chỉ các đối tượng (chuỗi cũng vậy).

Bạn có thể tạo các lược đồ và ánh xạ tùy chỉnh để cung cấp cho bạn toàn quyền kiểm soát cách dữ liệu của bạn có thể đi được bằng công cụ XPath. Lược đồ là cách xác định cách các phần tử, phần tử con, thuộc tính và giá trị nút được xác định trong dữ liệu của bạn. Sau đó, bạn có thể tạo biểu thức của riêng bạn cho phù hợp.

Cho rằng bạn có một biến được gọi là datachứa JSON từ câu hỏi, bạn có thể sử dụng jsel để viết:

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

Điều này sẽ trả về bất kỳ nút nào có idthuộc tính là 3. Một thuộc tính là bất kỳ giá trị nguyên thủy (chuỗi, số, ngày, regex) nào trong một đối tượng.


6

ObjectPath là ngôn ngữ truy vấn tương tự XPath hoặc JSONPath, nhưng mạnh hơn nhiều nhờ các tính toán số học nhúng, cơ chế so sánh và các hàm tích hợp. Xem cú pháp:

Tìm trong cửa hàng tất cả những đôi giày màu đỏ và giá dưới 50

$ .. giày. * [màu là "đỏ" và giá <50]


Tôi thích ví dụ đầu tiên trên trang web và thật tuyệt khi ObjectPath có thể chạy ở chế độ tương tác, giống như vỏ, nhưng điều tôi đang tìm kiếm là sử dụng ObjectPath trong tập lệnh Python. Bạn có thể chỉ cho tôi một ví dụ chỉ ra cách sử dụng ObjectPath làm thư viện không? Tôi không thể tìm thấy bất cứ điều gì như thế trên trang web.
piokuc

Vui lòng xem phần về cách sử dụng Python trên github . Chúng tôi sẽ thêm phần này vào trang web - thực sự rất khó tìm thấy vào lúc này. Nếu bạn cần thêm trợ giúp, bạn có thể đăng câu hỏi lên nhóm google .
Ela Bednarek

Cảm ơn bạn, Ela, các ví dụ được thêm trên trang github chính xác là những gì cần thiết.
piokuc

4

@Naftule - với "defiant.js", có thể truy vấn cấu trúc JSON bằng các biểu thức XPath. Kiểm tra đánh giá này để có được một ý tưởng về cách thức hoạt động:

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

Không giống như JSONPath, "defiant.js" cung cấp hỗ trợ toàn diện cho cú pháp truy vấn - của XPath trên các cấu trúc JSON.

Mã nguồn của defiant.js có thể được tìm thấy ở đây:
https://github.com/hbi99/defiant.js


3

JMESPath dường như rất phổ biến những ngày này (tính đến năm 2020) và giải quyết một số vấn đề với JSONPath. Nó có sẵn cho nhiều ngôn ngữ.


1

Nếu bạn giống tôi và bạn chỉ muốn thực hiện tra cứu dựa trên đường dẫn, nhưng không quan tâm đến XPath thực sự, thì lodash _.get()có thể hoạt động. Ví dụ từ các tài liệu lodash:

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'

Thật không may, chức năng đó chỉ có thể trả về một kết quả duy nhất, nó không hỗ trợ tìm nạp một loạt các mục phù hợp, đó là nơi các thư viện khác tỏa sáng.
Simon East

0

Thử thứ này đi - https://github.com/satyapaul/jpath/blob/master/JSONDataReader.java

Đây là một cách thực hiện rất đơn giản trên dòng xpath tương tự cho xml. Đó là tên như jpath.


1
Câu hỏi này được gắn thẻ javascript nhưng thư viện này dường như dành cho java
tripleee

Nó cũng có phiên bản Javascript - github.com/satyapaul/jpath/blob/master/jpath.js Đây là trang chủ của anh ấy cho dự án - github.com/satyapaul/jpath
Satyajit Paul
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.