XSLT tương đương với JSON [đã đóng]


411

XSLT tương đương với JSON không? Một cái gì đó cho phép tôi thực hiện các phép biến đổi trên JSON như XSLT làm với XML.


1
Btw, ngôn ngữ / nền tảng này sẽ được trên?
Staxman

6
@StaxMan XSLT là một tiêu chuẩn có triển khai thực tế ở nhiều ngôn ngữ và nền tảng, các câu hỏi của tôi nhắm đến một nỗ lực tương tự.
luvieere

36
+1 cho câu hỏi của bạn. Nhiều người dường như bỏ qua hoặc không thích XSLT, nhưng nó có thể chỉ đơn giản là một phản ứng đối với tính dài dòng của nó. Và thực sự, khi XML dần dần không còn được ưa chuộng, ngày càng có ít cơ hội sử dụng XSLT, thật đáng tiếc! Một XSLT tương đương với JSON sẽ rất tuyệt vời.
Nicolas Le Thierry d'Enơcanh

10
@ NicolasLeThierryd'Enơnh đồng ý. Rất nhiều người ghét XML và do đó loại bỏ XSLT. Hệ sinh thái các công cụ XML cũng nặng về các nhà phát triển Java, điều này làm mất đi nhiều người hơn nữa. Nhưng tôi đã say mê XSLT vào giữa những năm 2000 và có một sức mạnh to lớn không có tương đương trực tiếp bên ngoài hệ sinh thái XML. Tôi rất thích một JSON tương đương!
Zearin

Câu trả lời:


77

Ý tưởng thú vị. Một số tìm kiếm trên Google tạo ra một vài trang quan tâm, bao gồm:

Hi vọng điêu nay co ich.


10
Yup, cảm ơn bạn, đó là những gì tôi đang tìm kiếm. Thật đáng tiếc khi kỹ thuật này không phổ biến hơn, JSON thường được sử dụng làm định dạng trả về trong các dịch vụ kiểu REST và thật tuyệt khi có một cách tiêu chuẩn để thực hiện các phép biến đổi cho nó.
luvieere

8
Mã này sử dụng string.eval () ... :-(
dreftymac

Liên kết chỉ trả lời
Jean-François Fabre

102

Tương đương XSLT cho JSON - danh sách các ứng cử viên (công cụ và thông số kỹ thuật)

Công cụ

  1. XSLT

    Bạn có thể sử dụng XSLT cho JSON với mục đích là fn: json-to-xml .

    Phần này mô tả các cơ sở cho phép xử lý dữ liệu JSON bằng XSLT.

  2. jq

    jq giống như sed cho dữ liệu JSON - bạn có thể sử dụng nó để cắt và lọc và ánh xạ và biến đổi dữ liệu có cấu trúc một cách dễ dàng mà sed, awk, grep và bạn bè cho phép bạn chơi với văn bản. Có các gói cài đặt cho hệ điều hành khác nhau.

  3. jj

    JJ là một tiện ích dòng lệnh cung cấp một cách nhanh chóng và đơn giản để truy xuất hoặc cập nhật các giá trị từ các tài liệu JSON. Nó được cung cấp bởi GJSON và SJSON dưới mui xe.

  4. fx

    Công cụ xử lý JSON dòng lệnh

    • Không cần học cú pháp mới
    • JavaScript đơn giản
    • Định dạng và tô sáng
    • Nhị phân độc lập
  5. jl

    jl ("JSON lambda") là một ngôn ngữ chức năng nhỏ để truy vấn và thao tác JSON.

  6. JOLT

    Thư viện chuyển đổi JSON sang JSON được viết bằng Java trong đó "đặc tả" cho phép chuyển đổi tự nó là một tài liệu JSON.

  7. gron

    Làm cho JSON có thể greppable! gron chuyển đổi JSON thành các bài tập riêng biệt để giúp grep dễ dàng hơn cho những gì bạn muốn và xem 'đường dẫn' tuyệt đối đến nó. Nó giúp giảm bớt việc khám phá các API trả về các đốm lớn của JSON nhưng có tài liệu khủng.

  8. json

    json là một công cụ CLI nhanh để làm việc với JSON. Nó là một tập lệnh node.js một tập tin không có deps bên ngoài (ngoại trừ chính node.js).

  9. json-e

    JSON-e là một hệ thống tham số hóa cấu trúc dữ liệu để nhúng bối cảnh trong các đối tượng JSON. Ý tưởng trung tâm là coi cấu trúc dữ liệu là "khuôn mẫu" và biến đổi nó, sử dụng cấu trúc dữ liệu khác làm bối cảnh, để tạo ra cấu trúc dữ liệu đầu ra.

  10. Mã thông báo

    JSLT là một ngôn ngữ truy vấn và chuyển đổi hoàn chỉnh cho JSON. Thiết kế ngôn ngữ được lấy cảm hứng từ jq, XPath và XQuery.

  11. JSONata

    JSONata là một ngôn ngữ truy vấn và chuyển đổi nhẹ cho dữ liệu JSON. Lấy cảm hứng từ ngữ nghĩa của 'đường dẫn vị trí' của XPath 3.1, nó cho phép các truy vấn tinh vi được thể hiện bằng một ký hiệu nhỏ gọn và trực quan.

  12. json-Transforms Cam kết cuối cùng ngày 1 tháng 12 năm 2017

    Cung cấp một cách tiếp cận đệ quy, khớp mẫu để chuyển đổi dữ liệu JSON. Các phép biến đổi được định nghĩa là một tập hợp các quy tắc khớp với cấu trúc của một đối tượng JSON. Khi một trận đấu xảy ra, quy tắc sẽ phát ra dữ liệu được chuyển đổi, tùy ý đệ quy để biến đổi các đối tượng con.

  13. jsawk Cam kết cuối cùng vào ngày 4 tháng 3 năm 2015

    Jsawk giống như awk, nhưng đối với JSON. Bạn làm việc với một mảng các đối tượng JSON được đọc từ stdin, lọc chúng bằng JavaScript để tạo ra một mảng kết quả được in ra thiết bị xuất chuẩn.

  14. yate Cam kết cuối cùng ngày 13 tháng 3 năm 2017

    Các thử nghiệm có thể được sử dụng dưới dạng docu https://github.com/pasaran/yate/tree/master/tests

  15. jsonpath-object-Transform Cam kết cuối cùng ngày 18 tháng 1 năm 2017

    Kéo dữ liệu từ một đối tượng theo nghĩa đen bằng JSONPath và tạo một đối tượng mới dựa trên mẫu.

  16. Stapling Cam kết cuối cùng ngày 16 tháng 9 năm 2013

    Stapling là một thư viện JavaScript cho phép định dạng XSLT cho các đối tượng JSON. Thay vì sử dụng công cụ tạo khuôn mẫu JavaScript và các mẫu văn bản / html, Stapling cung cấp cho bạn cơ hội sử dụng các mẫu XSLT - được tải không đồng bộ với Ajax và sau đó được lưu vào bộ đệm của khách hàng - để phân tích các nguồn dữ liệu JSON của bạn.

Thông số kỹ thuật:

  • JsonPulum

    Con trỏ JSON xác định cú pháp chuỗi để xác định một giá trị cụ thể trong tài liệu Ký hiệu đối tượng JavaScript (JSON).

  • JsonPath

    Các biểu thức JSONPath luôn đề cập đến một cấu trúc JSON giống như cách biểu thức XPath được sử dụng kết hợp với một tài liệu XML

  • JSPath

    JSPath cho JSON giống như XPath cho XML. "

  • JSONiq

    Nguồn cảm hứng chính đằng sau JSONiq là XQuery, đã được chứng minh cho đến nay là một ngôn ngữ truy vấn thành công và hiệu quả cho dữ liệu bán cấu trúc


2
Cảm ơn bạn cho bài viết rất độc hại và hữu ích của bạn. Để chuyển đổi json một dòng thành dạng có thể đọc được, jq (nr.2 trong danh sách của bạn) là lựa chọn tốt nhất cho tôi. Cảm ơn một lần nữa!
Primehunter 15/03/19

1
Tôi thường sử dụng json_pp để in ấn đẹp. Nó có sẵn cho nhiều distro.
jschnasse

70

Hãy thử JOLT . Nó là một thư viện chuyển đổi JSON thành JSON được viết bằng Java.

Nó được tạo ra một cách cụ thể vì chúng tôi không muốn chơi trò chơi "JSON -> XML -> XSLT -> XML -> JSON" và sử dụng một khuôn mẫu cho bất kỳ biến đổi đủ phức tạp nào là không thể nhận ra.


4
+9000: Đây là một dự án nghiêm túc! Huzzah. Bản demo trực tuyến với các ví dụ giúp cải thiện khả năng học tập: jolt-demo.appspot.com
kevinarpe

15

jq - bộ xử lý JSON dòng lệnh nhẹ và linh hoạt

Nó không dựa trên mẫu như XSLT, nhưng ngắn gọn hơn. ví dụ để trích xuất nameaddresscác trường thành một mảng:[.name, .address]

Các hướng dẫn đi qua một ví dụ về chuyển JSON API của Twitter (và các nhãn hiệu có nhiều ví dụ).


4
Nó ngắn gọn hơn vì nó có khả năng ít hơn rất nhiều.
Ihe Onwuka 14/2/2015

Tôi không tìm thấy cách tìm đệ quy một thuộc tính đã cho trong cây Json
Daniel

@Daniel là .. | .attr_name?những gì bạn đang tìm kiếm? (từ stedolan.github.io/jq/manual/#RecursiveDescent: .. )
ankostis

1
Có thể không có khả năng như XSLT nhưng rất hữu ích và không phức tạp như XSLT
flq

15

XSLT hỗ trợ JSON như đã thấy tại http://www.w3.org/TR/xslt-30/#json

XML sử dụng dấu ngoặc nhọn cho mã thông báo dấu phân cách, JSON sử dụng dấu ngoặc nhọn, dấu ngoặc vuông, ... I. e. So sánh nhận dạng mã thông báo ít hơn của XML có nghĩa là nó được tối ưu hóa cho chuyển đổi khai báo, trong khi so sánh nhiều hơn, giống như câu lệnh chuyển đổi, vì lý do tốc độ giả định dự đoán nhánh đầu cơ rằng mã mệnh lệnh trong ngôn ngữ kịch bản là hữu ích cho. Do đó, đối với các hỗn hợp dữ liệu bán cấu trúc khác nhau, bạn có thể muốn đánh giá hiệu suất của XSLT và công cụ javascript như một phần của các trang phản hồi. Đối với tải trọng dữ liệu không đáng kể, các phép biến đổi có thể hoạt động tốt như với JSON mà không cần tuần tự hóa XML. Quyết định của W3 nên dựa trên phân tích tốt hơn.


15

Gần đây tôi đã tìm thấy một công cụ mà tôi yêu thích để tạo kiểu JSON: https://github.com/twigkit/tempo . Công cụ rất dễ sử dụng - theo tôi, nó hoạt động dễ dàng hơn nhiều so với XSLT - không cần truy vấn XPATH.


9
Tempo trông tuyệt vời nếu kết quả cuối cùng của chuyển đổi là HTML. Nhưng điều gì sẽ xảy ra nếu bạn chỉ muốn sắp xếp lại một cấu trúc ngụ ý thành một cấu trúc khác, nhưng kết quả cuối cùng vẫn là JSON. Tôi vẫn muốn có một sự tương tự của XPath để tôi có thể viết phép biến đổi theo cách chức năng.
Toddius Zho

1
Tempo rất thú vị thực sự cảm ơn bạn. Tuy nhiên, bạn có thể gửi xml đến trình duyệt và xslt (<? Xsl-Stylesheet>) và trình duyệt của bạn sẽ áp dụng xslt cho xml, hiển thị chế độ xem được xác định của xml mà không cần thêm mã. Đây cũng là trường hợp cho jsonT / tempo.
Martin Meeser


11

Để nói thiếu công cụ cho thấy thiếu nhu cầu chỉ là cầu xin câu hỏi. Điều tương tự cũng có thể được áp dụng để hỗ trợ X hoặc Y trong Linux (Tại sao phải phát triển trình điều khiển và / hoặc trò chơi chất lượng cho một HĐH thiểu số như vậy? Và tại sao phải chú ý đến một HĐH mà các công ty trò chơi và phần cứng lớn không phát triển?). Có lẽ những người sẽ cần sử dụng XSLT và JSON kết thúc bằng cách sử dụng một cách giải quyết có phần tầm thường: Chuyển đổi JSON thành XML. Nhưng đó không phải là giải pháp tối ưu, phải không?

Khi bạn có định dạng JSON gốc và bạn muốn chỉnh sửa nó "wysywyg" trong trình duyệt, XSLT sẽ là một giải pháp phù hợp hơn cho vấn đề. Làm điều đó với lập trình javascript truyền thống có thể trở thành một nỗi đau ở mông.

Trên thực tế, tôi đã triển khai cách tiếp cận "thời đồ đá" cho XSLT, sử dụng phân tích cú pháp chuỗi con để diễn giải một số lệnh cơ bản cho javascript, như gọi một mẫu, xử lý trẻ em, v.v ... Chắc chắn việc triển khai một công cụ chuyển đổi với đối tượng JSON dễ dàng hơn nhiều triển khai trình phân tích cú pháp XML đầy đủ để phân tích XSLT. Vấn đề là, để sử dụng các mẫu XML để chuyển đổi một đối tượng JSON, bạn cần phân tích cú pháp XML của các mẫu.

Để định dạng một đối tượng JSON bằng XML (hoặc HTML hoặc văn bản hoặc bất cứ điều gì), bạn cần suy nghĩ cẩn thận về cú pháp và những ký tự đặc biệt bạn cần sử dụng để xác định các lệnh chuyển đổi. Nếu không, bạn sẽ phải thiết kế một trình phân tích cú pháp cho ngôn ngữ tạo khuôn mẫu tùy chỉnh của riêng bạn. Đã đi qua con đường đó, tôi có thể nói với bạn rằng nó không đẹp.

Cập nhật (ngày 12 tháng 11 năm 2010): Sau một vài tuần làm việc với trình phân tích cú pháp của tôi, tôi đã có thể tối ưu hóa nó. Các mẫu được phân tích cú pháp trước và các lệnh được lưu trữ dưới dạng các đối tượng JSON. Các quy tắc chuyển đổi cũng là các đối tượng JSON, trong khi mã mẫu là sự pha trộn của HTML và cú pháp homebrew tương tự như mã shell. Tôi đã có thể chuyển đổi một tài liệu JSON phức tạp thành HTML để làm trình chỉnh sửa tài liệu. Mã này có khoảng 1K dòng cho trình soạn thảo (nó dành cho một dự án riêng vì vậy tôi không thể chia sẻ nó) và khoảng 990 dòng cho mã chuyển đổi JSON (bao gồm các lệnh lặp, so sánh đơn giản, gọi mẫu, lưu và đánh giá biến). Tôi dự định phát hành nó theo giấy phép MIT. Thả tôi một mail nếu bạn muốn tham gia.


11

Tôi đã viết thư viện nhỏ của riêng mình xung quanh đây, gần đây, nó cố gắng ở gần

5.1 Mô hình xử lý (XSLT REC) https://www.w3.org/TR/xslt#section-Processing-Model

như có thể (dù sao tôi cũng có thể), trong một vài dòng mã JavaScript.

Dưới đây là một vài ví dụ không hoàn toàn tầm thường về việc sử dụng ...

1. JSON-to-some-markup:

Fiddle: https://jsfiddle.net/YSharpL Language /kj9pk8oz / 10

(lấy cảm hứng từ Ví dụ tài liệu D.1 (XSLT REC) https://www.w3.org/TR/xslt#section-Document-Example )

cái đó ở đâu:

var D1document = {
    type: "document", title: [ "Document Title" ],
    "": [
      { type: "chapter", title: [ "Chapter Title" ],
        "": [
        { type: "section", title: [ "Section Title" ],
          "": [
            { type: "para", "": [ "This is a test." ] },
            { type: "note", "": [ "This is a note." ] }
        ] },
        { type: "section", title: [ "Another Section Title" ],
          "": [
            { type: "para", "": [ "This is ", { emph: "another" }, " test." ] },
            { type: "note", "": [ "This is another note." ] }
        ] }
      ] }
    ] };

var D1toHTML = { $: [
  [ [ function(node) { return node.type === "document"; } ],
    function(root) {
      return "<html>\r\n\
  <head>\r\n\
    <title>\r\n\
      {title}\r\n".of(root) + "\
    </title>\r\n\
  </head>\r\n\
  <body>\r\n\
{*}".of(root[""].through(this)) + "\
  </body>\r\n\
</html>";
    }
  ],
  [ [ function(node) { return node.type === "chapter"; } ],
    function(chapter) {
      return "    <h2>{title}</h2>\r\n".of(chapter) + "{*}".of(chapter[""].through(this));
    }
  ],
  [ [ function(node) { return node.type === "section"; } ],
    function(section) {
      return "    <h3>{title}</h3>\r\n".of(section) + "{*}".of(section[""].through(this));
    }
  ],
  [ [ function(node) { return node.type === "para"; } ],
    function(para) {
      return "    <p>{*}</p>\r\n".of(para[""].through(this));
    }
  ],
  [ [ function(node) { return node.type === "note"; } ],
    function(note) {
      return '    <p class="note"><b>NOTE: </b>{*}</p>\r\n'.of(note[""].through(this));
    }
  ],
  [ [ function(node) { return node.emph; } ],
    function(emph) {
      return "<em>{emph}</em>".of(emph);
    }
  ]
] };

console.log(D1document.through(D1toHTML));

... cho:

<html>
  <head>
    <title>
      Document Title
    </title>
  </head>
  <body>
    <h2>Chapter Title</h2>
    <h3>Section Title</h3>
    <p>This is a test.</p>
    <p class="note"><b>NOTE: </b>This is a note.</p>
    <h3>Another Section Title</h3>
    <p>This is <em>another</em> test.</p>
    <p class="note"><b>NOTE: </b>This is another note.</p>
  </body>
</html>

2. JSON-to-JSON:

Fiddle: https://jsfiddle.net/YSharpL Language / pfmmmm15 / 10

cái đó ở đâu:

// (A "Company" is just an object with a "Team")
function Company(obj) {
  return obj.team && Team(obj.team);
}

// (A "Team" is just a non-empty array that contains at least one "Member")
function Team(obj) {
  return ({ }.toString.call(obj) === "[object Array]") &&
         obj.length &&
         obj.find(function(item) { return Member(item); });
}

// (A "Member" must have first and last names, and a gender)
function Member(obj) {
  return obj.first && obj.last && obj.sex;
}

function Dude(obj) {
  return Member(obj) && (obj.sex === "Male");
}

function Girl(obj) {
  return Member(obj) && (obj.sex === "Female");
}

var data = { team: [
  { first: "John", last: "Smith", sex: "Male" },
  { first: "Vaio", last: "Sony" },
  { first: "Anna", last: "Smith", sex: "Female" },
  { first: "Peter", last: "Olsen", sex: "Male" }
] };

var TO_SOMETHING_ELSE = { $: [

  [ [ Company ],
    function(company) {
      return { some_virtual_dom: {
        the_dudes: { ul: company.team.select(Dude).through(this) },
        the_grrls: { ul: company.team.select(Girl).through(this) }
      } }
    } ],

  [ [ Member ],
    function(member) {
      return { li: "{first} {last} ({sex})".of(member) };
    } ]

] };

console.log(JSON.stringify(data.through(TO_SOMETHING_ELSE), null, 4));

... cho:

{
    "some_virtual_dom": {
        "the_dudes": {
            "ul": [
                {
                    "li": "John Smith (Male)"
                },
                {
                    "li": "Peter Olsen (Male)"
                }
            ]
        },
        "the_grrls": {
            "ul": [
                {
                    "li": "Anna Smith (Female)"
                }
            ]
        }
    }
}

3. XSLT so với JavaScript:

Một JavaScript tương đương với ...

XSLT 3.0 REC Phần 14.4 Ví dụ: Nhóm các nút dựa trên các giá trị chung

(tại: http://jsfiddle.net/YSharpL Language / 8bqcd0ey / 1 )

Cf. https://www.w3.org/TR/xslt-30/#grouping-examples

Ở đâu...

var cities = [
  { name: "Milano",  country: "Italia",      pop: 5 },
  { name: "Paris",   country: "France",      pop: 7 },
  { name: "München", country: "Deutschland", pop: 4 },
  { name: "Lyon",    country: "France",      pop: 2 },
  { name: "Venezia", country: "Italia",      pop: 1 }
];

/*
  Cf.
  XSLT 3.0 REC Section 14.4
  Example: Grouping Nodes based on Common Values

  https://www.w3.org/TR/xslt-30/#grouping-examples
*/
var output = "<table>\r\n\
  <tr>\r\n\
    <th>Position</th>\r\n\
    <th>Country</th>\r\n\
    <th>City List</th>\r\n\
    <th>Population</th>\r\n\
  </tr>{*}\r\n\
</table>".of
  (
    cities.select().groupBy("country")(function(byCountry, index) {
      var country = byCountry[0],
          cities = byCountry[1].select().orderBy("name");
      return "\r\n\
  <tr>\r\n\
    <td>{position}</td>\r\n\
    <td>{country}</td>\r\n\
    <td>{cities}</td>\r\n\
    <td>{population}</td>\r\n\
  </tr>".
        of({ position: index + 1, country: country,
             cities: cities.map(function(city) { return city.name; }).join(", "),
             population: cities.reduce(function(sum, city) { return sum += city.pop; }, 0)
           });
    })
  );

... cho:

<table>
  <tr>
    <th>Position</th>
    <th>Country</th>
    <th>City List</th>
    <th>Population</th>
  </tr>
  <tr>
    <td>1</td>
    <td>Italia</td>
    <td>Milano, Venezia</td>
    <td>6</td>
  </tr>
  <tr>
    <td>2</td>
    <td>France</td>
    <td>Lyon, Paris</td>
    <td>9</td>
  </tr>
  <tr>
    <td>3</td>
    <td>Deutschland</td>
    <td>München</td>
    <td>4</td>
  </tr>
</table>

4. JSONiq so với JavaScript:

Một JavaScript tương đương với ...

Các trường hợp sử dụng JSONiq Phần 1.1.2. Truy vấn nhóm cho JSON

(tại: https://jsfiddle.net/YSharpL Language / hvo24hmk / 3 )

Cf. http://jsoniq.org/docs/JSONiq-usecase/html-single/index.html#jsongrouping

Ở đâu...

/*
  1.1.2. Grouping Queries for JSON
  http://jsoniq.org/docs/JSONiq-usecases/html-single/index.html#jsongrouping
*/
var sales = [
  { "product" : "broiler", "store number" : 1, "quantity" : 20  },
  { "product" : "toaster", "store number" : 2, "quantity" : 100 },
  { "product" : "toaster", "store number" : 2, "quantity" : 50 },
  { "product" : "toaster", "store number" : 3, "quantity" : 50 },
  { "product" : "blender", "store number" : 3, "quantity" : 100 },
  { "product" : "blender", "store number" : 3, "quantity" : 150 },
  { "product" : "socks", "store number" : 1, "quantity" : 500 },
  { "product" : "socks", "store number" : 2, "quantity" : 10 },
  { "product" : "shirt", "store number" : 3, "quantity" : 10 }
];

var products = [
  { "name" : "broiler", "category" : "kitchen", "price" : 100, "cost" : 70 },
  { "name" : "toaster", "category" : "kitchen", "price" : 30, "cost" : 10 },
  { "name" : "blender", "category" : "kitchen", "price" : 50, "cost" : 25 },
  {  "name" : "socks", "category" : "clothes", "price" : 5, "cost" : 2 },
  { "name" : "shirt", "category" : "clothes", "price" : 10, "cost" : 3 }
];

var stores = [
  { "store number" : 1, "state" : "CA" },
  { "store number" : 2, "state" : "CA" },
  { "store number" : 3, "state" : "MA" },
  { "store number" : 4, "state" : "MA" }
];

var nestedGroupingAndAggregate = stores.select().orderBy("state").groupBy("state")
( function(byState) {
    var state = byState[0],
        stateStores = byState[1];
    byState = { };
    return (
      (
        byState[state] =
        products.select().orderBy("category").groupBy("category")
        ( function(byCategory) {
            var category = byCategory[0],
                categoryProducts = byCategory[1],
                categorySales = sales.filter(function(sale) {
                  return stateStores.find(function(store) { return sale["store number"] === store["store number"]; }) &&
                         categoryProducts.find(function(product) { return sale.product === product.name; });
                });
            byCategory = { };
            return (
              (
                byCategory[category] =
                categorySales.select().orderBy("product").groupBy("product")
                ( function(byProduct) {
                    var soldProduct = byProduct[0],
                        soldQuantities = byProduct[1];
                    byProduct = { };
                    return (
                      (
                        byProduct[soldProduct] =
                        soldQuantities.reduce(function(sum, sale) { return sum += sale.quantity; }, 0)
                      ),
                      byProduct
                    );
                } ) // byProduct()
              ),
              byCategory
            );
        } ) // byCategory()
      ),
      byState
    );
} ); // byState()

... cho:

[
  {
    "CA": [
      {
        "clothes": [
          {
            "socks": 510
          }
        ]
      },
      {
        "kitchen": [
          {
            "broiler": 20
          },
          {
            "toaster": 150
          }
        ]
      }
    ]
  },
  {
    "MA": [
      {
        "clothes": [
          {
            "shirt": 10
          }
        ]
      },
      {
        "kitchen": [
          {
            "blender": 250
          },
          {
            "toaster": 50
          }
        ]
      }
    ]
  }
]

Nó cũng hữu ích để khắc phục những hạn chế của JSONPath wrt. truy vấn theo trục tổ tiên, như được nêu ra bởi câu hỏi SO này (và chắc chắn là những câu hỏi khác).

Ví dụ: làm thế nào để có được giảm giá của một mặt hàng tạp hóa biết id thương hiệu của nó, trong

{
 "prods": [
    {
        "info": {
              "rate": 85
                },
        "grocery": [
                 {
                  "brand": "C",
                  "brand_id": "984"
                 },
                 {
                  "brand": "D",
                  "brand_id": "254"
                 }
                 ],
         "discount": "15"
    },
    {
        "info": {
              "rate": 100
                },
        "grocery": [
                 {
                  "brand": "A",
                  "brand_id": "983"
                 },
                 {
                  "brand": "B",
                  "brand_id": "253"
                 }
                 ],
         "discount": "20"
     }
 ]
}

?

Một giải pháp khả thi là:

var products = {
     "prods": [
        {
            "info": {
                  "rate": 85
                    },
            "grocery": [
                     {
                      "brand": "C",
                      "brand_id": "984"
                     },
                     {
                      "brand": "D",
                      "brand_id": "254"
                     }
                     ],
             "discount": "15"
        },
        {
            "info": {
                  "rate": 100
                    },
            "grocery": [
                     {
                      "brand": "A",
                      "brand_id": "983"
                     },
                     {
                      "brand": "B",
                      "brand_id": "253"
                     }
                     ],
             "discount": "20"
         }
     ]
};

function GroceryItem(obj) {
  return (typeof obj.brand === "string") && (typeof obj.brand_id === "string");
}

    // last parameter set to "true", to grab all the "GroceryItem" instances
    // at any depth:
var itemsAndDiscounts = [ products ].nodeset(GroceryItem, true).
    map(
      function(node) {
        var item = node.value, // node.value: the current "GroceryItem" (aka "$.prods[*].grocery[*]")

            discount = node.parent. // node.parent: the array of "GroceryItem" (aka "$.prods[*].grocery")
                       parent. // node.parent.parent: the product (aka "$.prods[*]")
                       discount; // node.parent.parent.discount: the product discount

        // finally, project into an easy-to-filter form:
        return { id: item.brand_id, discount: discount };
      }
    ),
    discountOfItem983;

discountOfItem983 = itemsAndDiscounts.
  filter
  (
    function(mapped) {
      return mapped.id === "983";
    }
  )
  [0].discount;

console.log("Discount of #983: " + discountOfItem983);

... mang lại:

Discount of #983: 20

'HTH,


10

Có ngay bây giờ! Gần đây tôi đã tạo một thư viện, json-Transforms , chính xác cho mục đích này:

https://github.com/ColinEberhardt/json-transforms

Nó sử dụng một sự kết hợp của JSPath , DSL được mô hình hóa trên XPath và một cách tiếp cận khớp mẫu đệ quy, lấy cảm hứng trực tiếp từ XSLT.

Đây là một ví dụ nhanh. Cho đối tượng JSON sau:

const json = {
  "automobiles": [
    { "maker": "Nissan", "model": "Teana", "year": 2011 },
    { "maker": "Honda", "model": "Jazz", "year": 2010 },
    { "maker": "Honda", "model": "Civic", "year": 2007 },
    { "maker": "Toyota", "model": "Yaris", "year": 2008 },
    { "maker": "Honda", "model": "Accord", "year": 2011 }
  ]
};

Đây là một sự chuyển đổi:

const jsont = require('json-transforms');
const rules = [
  jsont.pathRule(
    '.automobiles{.maker === "Honda"}', d => ({
      Honda: d.runner()
    })
  ),
  jsont.pathRule(
    '.{.maker}', d => ({
      model: d.match.model,
      year: d.match.year
    })
  ),
  jsont.identity
];

const transformed  = jsont.transform(json, rules);

Đầu ra nào sau đây:

{
  "Honda": [
    { "model": "Jazz", "year": 2010 },
    { "model": "Civic", "year": 2007 },
    { "model": "Accord", "year": 2011 }
  ]
}

Biến đổi này bao gồm ba quy tắc. Chiếc đầu tiên phù hợp với bất kỳ chiếc ô tô nào được sản xuất bởi Honda, phát ra một vật thể có Hondatài sản, sau đó khớp theo cách đệ quy. Quy tắc thứ hai khớp với bất kỳ đối tượng nào có thuộc makertính, xuất ra các thuộc tính modelyear. Cuối cùng là biến đổi danh tính phù hợp đệ quy.


9

Như một câu trả lời mới khác cho một câu hỏi cũ, tôi đề nghị một cái nhìn về DefiantJS . Nó không phải là XSLT tương đương với JSON, nó XSLT cho JSON. Phần "Templating" của tài liệu bao gồm ví dụ này:

<!-- Defiant template -->
<script type="defiant/xsl-template">
    <xsl:template name="books_template">
        <xsl:for-each select="//movie">
            <xsl:value-of select="title"/><br/>
        </xsl:for-each>
    </xsl:template>
</script>

<script type="text/javascript">

var data = {
        "movie": [
            {"title": "The Usual Suspects"},
            {"title": "Pulp Fiction"},
            {"title": "Independence Day"}
        ]
    },
    htm = Defiant.render('books_template', data);

console.log(htm);
// The Usual Suspects<br>
// Pulp Fiction<br>
// Independence Day<br>

5

Tôi đã thực sự mệt mỏi với số lượng lớn các công cụ tạo khuôn mẫu JavaScript ngoài đó và tất cả các mẫu HTML nội tuyến, các kiểu đánh dấu khác nhau, v.v., và đã quyết định xây dựng một thư viện nhỏ cho phép định dạng XSLT cho các cấu trúc dữ liệu JSON. Không phải khoa học tên lửa theo bất kỳ cách nào - đó chỉ là JSON được phân tích cú pháp thành XML và sau đó được định dạng bằng tài liệu XSLT. Nó cũng nhanh, không nhanh bằng các công cụ mẫu JavaScript trong Chrome, nhưng trong hầu hết các trình duyệt khác, nó ít nhất cũng nhanh như công cụ JS thay thế cho các cấu trúc dữ liệu lớn hơn.


4

Tôi đang sử dụng Camel tuyến umarshal (xmljson) -> to (xlst) -> marshal (xmljson). Đủ hiệu quả (mặc dù không hoàn hảo 100%), nhưng đơn giản, nếu bạn đã sử dụng Camel.


3

JSONiq là một tiêu chuẩn như vậy và Zorba là một triển khai C ++ nguồn mở. JSONiq cũng có thể được xem là XQuery với việc thêm JSON làm kiểu dữ liệu gốc.



2

Yate ( https://github.com/pasaran/yate ) được thiết kế đặc biệt sau XSLT, có tính năng JPath (tương đương XPath tự nhiên cho JS), biên dịch sang JavaScript và có lịch sử sử dụng sản xuất. Nó thực tế không có giấy tờ, nhưng đọc qua các mẫu và kiểm tra là đủ.


2

JSLT rất gần với tương đương JSON của XSLT. Đó là ngôn ngữ biến đổi trong đó bạn viết phần cố định của đầu ra theo cú pháp JSON, sau đó chèn biểu thức để tính các giá trị bạn muốn chèn trong mẫu.

Một ví dụ:

{
  "time": round(parse-time(.published, "yyyy-MM-dd'T'HH:mm:ssX") * 1000),
  "device_manufacturer": .device.manufacturer,
  "device_model": .device.model,
  "language": .device.acceptLanguage
}

Nó được triển khai trên Java trên đỉnh Jackson.


0

Không quá chắc chắn là có nhu cầu này, và với tôi thiếu công cụ cho thấy thiếu nhu cầu. JSON được xử lý tốt nhất dưới dạng các đối tượng (dù sao nó cũng được thực hiện trong JS) và bạn thường sử dụng ngôn ngữ của chính các đối tượng để thực hiện các phép biến đổi (Java cho các đối tượng Java được tạo từ JSON, tương tự cho Perl, Python, Perl, c #, PHP, v.v. trên). Chỉ với các bài tập bình thường (hoặc đặt, nhận), lặp và vân vân.

Ý tôi là, XSLT chỉ là một ngôn ngữ khác và một lý do cần thiết là XML không phải là một ký hiệu đối tượng và do đó các đối tượng của ngôn ngữ lập trình không phù hợp chính xác (trở kháng giữa mô hình xml phân cấp và các đối tượng / cấu trúc).


Sau khi Facebook chuyển đổi từ XML sang Json, tôi rất cần một công cụ như thế này.
Joe Soul-bringer

Bạn đang nghĩ gì về trường hợp sử dụng? Có phải nó có thể hiển thị nội dung JSON tương tự như cách bạn kết xuất các phản hồi XML dưới dạng HTML không? Hay một cái gì đó khác nhau?
StaxMan

Tôi tự hỏi làm thế nào dễ dàng để thao tác chuyển đổi JSON theo cách đối tượng lập trình (w / looping, phân nhánh khi cần, v.v.) so với sử dụng phương thức loại XSLT, đặc biệt là trong trường hợp chuyển đổi đối tượng JSON lớn và khi một số dữ liệu trong JSON nguồn được dịch chuyển lên / xuống một số nút trong JSON đích (vì vậy không chỉ đơn giản là bản sao trực tiếp của cấu trúc) và nói rằng một nút cụ thể trong JSON hoặc nguồn đích là một phần của mảng đối tượng trong JSON và JSON (nguồn / đích) khác không .
David

Dễ là rất chủ quan, vì vậy tôi nghi ngờ nhiều về nó có liên quan đến những gì người ta đã quen.
StaxMan

Mặc dù chắc chắn cần phải chuyển đổi JSON, nhưng bạn nói đúng, nó hầu như được đáp ứng bởi JS. :-) Nhưng bạn đã thấy jq - bộ xử lý JSON dòng lệnh nhẹ và linh hoạt chưa? Đặc biệt là khi JS không có sẵn. Tôi muốn nói rằng việc chuyển đổi dễ dàng hơn và trực quan hơn, thậm chí còn hơn cả JS. ví dụ: để trích xuất các trường nameaddressđặt chúng vào một mảng:[.name, .address]
13ren

0

Tại sao bạn không chuyển đổi JSON thành XML bằng cách sử dụng Mr. Data Coverter , định dạng lại nó bằng XSLT và sau đó thay đổi lại thành JSON bằng cách sử dụng tương tự.


1
Đó không phải là một lựa chọn nếu bạn muốn mã của bạn làm điều đó cho bạn với hiệu suất tốt.
orad

0

Để biết cách vẽ nguệch ngoạc / bằng chứng về khái niệm về cách tiếp cận để sử dụng JavaScript thuần cùng với mẫu khai báo và quen thuộc đằng sau các biểu thức khớp và các mẫu đệ quy của XSLT, hãy xem https://gist.github.com/brettz9/0e661b3093764f496e36

(Một cách tiếp cận tương tự có thể được thực hiện cho JSON.)

Lưu ý rằng bản demo cũng dựa trên các đóng biểu thức JavaScript 1.8 để thuận tiện trong việc thể hiện các mẫu trong Firefox (ít nhất là cho đến khi mẫu ngắn ES6 cho các phương thức có thể được triển khai).

Disclaimer: Đây là mã của riêng tôi.


0

Tôi đã viết một bộ chuyển đổi dom cho khung xử lý json dựa trên jackson của tôi từ lâu. Nó sử dụng thư viện nu.xom. Cây dom kết quả hoạt động với các tiện ích java xpath và xslt. Tôi đã thực hiện một số lựa chọn thực hiện khá đơn giản. Ví dụ, nút gốc luôn được gọi là "root", các mảng đi vào một nút ol với các phần tử phụ li (như trong html) và mọi thứ khác chỉ là một nút phụ có giá trị nguyên thủy hoặc nút đối tượng khác.

JsonXmlConverter.java

Sử dụng: JsonObject sampleJson = sampleJson(); org.w3c.dom.Document domNode = JsonXmlConverter.getW3cDocument(sampleJson, "root");


0

Một cách tiếp cận chưa được đưa ra là sử dụng trình tạo trình phân tích cú pháp để tạo trình phân tích cú pháp trong XSLT để phân tích cú pháp JSON và tạo đầu ra XML.

Một tùy chọn được đề cập rất nhiều tại các hội nghị XML là trình tạo trình phân tích cú pháp ReX ( http://www.bottlecaps.de/rex/ ) - mặc dù hoàn toàn không có tài liệu trên trang web, các công thức nấu ăn có sẵn khi tìm kiếm.


0

Có thể sử dụng XSLT với JSON. Verson 3 của XPath (3.1) XSLT (3.0) và XQuery (3.1) theo cách nào đó hỗ trợ JSON. Điều này dường như có sẵn trong phiên bản thương mại của Saxon và đôi khi có thể được đưa vào phiên bản HE. https://www.saxonica.com/html/documentation/fifts/fn/parse-json.html

-

Những gì tôi mong đợi từ một giải pháp thay thế:

Tôi muốn có thể nhập JSON để tìm nạp một tập hợp dữ liệu phù hợp và xuất JSON hoặc TEXT.

Truy cập các thuộc tính tùy ý và đánh giá các giá trị

Hỗ trợ logic điều kiện

Tôi muốn các tập lệnh chuyển đổi nằm ngoài công cụ, dựa trên văn bản và tốt nhất là một ngôn ngữ thường được sử dụng.

Tiềm năng thay thế?

Tôi tự hỏi nếu SQL có thể là một sự thay thế phù hợp. https://docs.microsoft.com/en-us/sql/relational-database/json/json-data-sql-server

Sẽ thật tuyệt nếu công cụ thay thế có thể xử lý JSON và XML https://docs.microsoft.com/en-us/sql/relational-database/xml/openxml-sql-server

Tôi chưa thử chuyển đổi các tập lệnh XSLT mà tôi sử dụng sang SQL hoặc đã đánh giá đầy đủ tùy chọn này, nhưng tôi hy vọng sẽ sớm xem xét nó. Chỉ là một vài suy nghĩ cho đến nay.

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.