JSON 的 XSLT 等效项

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1618038/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 17:21:00  来源:igfitidea点击:

XSLT equivalent for JSON

jsonxsltequivalentlanguage-comparisons

提问by luvieere

Is there an XSLTequivalent for JSON? Something to allow me to do transformations on JSON like XSLT does to XML.

JSON是否有XSLT等价物?允许我对 JSON 进行转换,就像 XSLT 对 XML 所做的那样。

采纳答案by Tim

Interesting idea. Some searching on Google produced a few pages of interest, including:

有趣的想法。在 Google 上的一些搜索产生了一些有趣的页面,包括:

Hope this helps.

希望这可以帮助。

回答by jschnasse

XSLT equivalents for JSON - a list of candidates (tools and specs)

JSON 的 XSLT 等效项 - 候选列表(工具和规范)

Tools

工具

  1. XSLT

    You can use XSLT for JSONwith the aim of fn:json-to-xml.

    This section describes facilities allowing JSON data to be processed using XSLT.

  2. jq

    jq is like sed for JSON data - you can use it to slice and filter and map and transform structured data with the same ease that sed, awk, grep and friends let you play with text. There are install packages for different OS.

  3. jj

    JJ is a command line utility that provides a fast and simple way to retrieve or update values from JSON documents. It's powered by GJSON and SJSON under the hood.

  4. fx

    Command-line JSON processing tool

    • Don't need to learn new syntax
    • Plain JavaScript
    • Formatting and highlighting
    • Standalone binary
  5. jl

    jl ("JSON lambda") is a tiny functional language for querying and manipulating JSON.

  6. JOLT

    JSON to JSON transformation library written in Java where the "specification" for the transform is itself a JSON document.

  7. gron

    Make JSON greppable! gron transforms JSON into discrete assignments to make it easier to grep for what you want and see the absolute 'path' to it. It eases the exploration of APIs that return large blobs of JSON but have terrible documentation.

  8. json

    json is a fast CLI tool for working with JSON. It is a single-file node.js script with no external deps (other than node.js itself).

  9. json-e

    JSON-e is a data-structure parameterization system for embedding context in JSON objects. The central idea is to treat a data structure as a "template" and transform it, using another data structure as context, to produce an output data structure.

  10. JSLT

    JSLT is a complete query and transformation language for JSON. The language design is inspired by jq, XPath, and XQuery.

  11. JSONata

    JSONata is a lightweight query and transformation language for JSON data. Inspired by the 'location path' semantics of XPath 3.1, it allows sophisticated queries to be expressed in a compact and intuitive notation.

  12. json-transformsLast Commit Dec 1, 2017

    Provides a recursive, pattern-matching approach to transforming JSON data. Transformations are defined as a set of rules which match the structure of a JSON object. When a match occurs, the rule emits the transformed data, optionally recursing to transform child objects.

  13. jsawkLast commit Mar 4, 2015

    Jsawk is like awk, but for JSON. You work with an array of JSON objects read from stdin, filter them using JavaScript to produce a results array that is printed to stdout.

  14. yateLast Commit Mar 13, 2017

    Tests can be used as docu https://github.com/pasaran/yate/tree/master/tests

  15. jsonpath-object-transformLast Commit Jan 18, 2017

    Pulls data from an object literal using JSONPath and generate a new objects based on a template.

  16. StaplingLast Commit Sep 16, 2013

    Stapling is a JavaScript library that enables XSLT formatting for JSON objects. Instead of using a JavaScript templating engine and text/html templates, Stapling gives you the opportunity to use XSLT templates - loaded asynchronously with Ajax and then cached client side - to parse your JSON datasources.

  1. XSLT

    您可以将XSLT 用于 JSON以达到fn:json-to-xml 的目的

    本节描述允许使用 XSLT 处理 JSON 数据的工具。

  2. 知乎

    jq 就像用于 JSON 数据的 sed - 您可以使用它来切片、过滤、映射和转换结构化数据,就像 sed、awk、grep 和朋友让您处理文本一样轻松。有适用于不同操作系统的安装包。

  3. jj

    JJ 是一个命令行实用程序,它提供了一种快速而简单的方法来检索或更新 JSON 文档中的值。它由 GJSON 和 SJSON 提供支持。

  4. 外汇

    命令行JSON处理工具

    • 不需要学习新语法
    • 纯 JavaScript
    • 格式化和突出显示
    • 独立二进制
  5. 杰尔

    jl(“JSON lambda”)是一种用于查询和操作 JSON 的微型函数式语言。

  6. 颠簸

    用 Java 编写的 JSON 到 JSON 转换库,其中转换的“规范”本身就是一个 JSON 文档。

  7. 格隆

    使 JSON grepable!gron 将 JSON 转换为离散分配,以便更轻松地 grep 查找您想要的内容并查看它的绝对“路径”。它简化了对返回大量 JSON 但具有糟糕文档的 API 的探索。

  8. json

    json 是一个用于处理 JSON 的快速 CLI 工具。它是一个单文件 node.js 脚本,没有外部 deps(除了 node.js 本身)。

  9. json-e

    JSON-e 是一种数据结构参数化系统,用于在 JSON 对象中嵌入上下文。中心思想是将数据结构视为“模板”,并使用另一个数据结构作为上下文对其进行转换,以生成输出数据结构。

  10. JSLT

    JSLT 是一种完整的 JSON 查询和转换语言。语言设计的灵感来自 jq、XPath 和 XQuery。

  11. 数据集

    JSONata 是一种用于 JSON 数据的轻量级查询和转换语言。受 XPath 3.1 的“位置路径”语义的启发,它允许以简洁直观的符号表示复杂的查询。

  12. json-transforms上次提交 2017 年 12 月 1 日

    提供一种递归的模式匹配方法来转换 JSON 数据。转换被定义为一组匹配 JSON 对象结构的规则。当匹配发生时,规则发出转换后的数据,可选地递归转换子对象。

  13. jsawk最后一次提交 2015 年 3 月 4 日

    Jsawk 类似于 awk,但用于 JSON。您使用从 stdin 读取的 JSON 对象数组,使用 JavaScript 过滤它们以生成打印到 stdout 的结果数组。

  14. yate最后提交 2017 年 3 月 13 日

    测试可以用作文档https://github.com/pasaran/yate/tree/master/tests

  15. jsonpath-object-transform上次提交 2017 年 1 月 18 日

    使用 JSONPath 从对象文字中提取数据并基于模板生成新对象。

  16. 装订上次提交 2013 年 9 月 16 日

    Stapling 是一个 JavaScript 库,可为 JSON 对象启用 XSLT 格式。Stapling 不是使用 JavaScript 模板引擎和 text/html 模板,而是让您有机会使用 XSLT 模板(通过 Ajax 异步加载然后缓存客户端)来解析您的 JSON 数据源。

Specs:

眼镜:

  • JsonPointer

    JSON Pointer defines a string syntax for identifying a specific value within a JavaScript Object Notation (JSON) document.

  • JsonPath

    JSONPath expressions always refer to a JSON structure in the same way as XPath expression are used in combination with an XML document

  • JSPath

    JSPath for JSON is like XPath for XML."

  • JSONiq

    The main source of inspiration behind JSONiq is XQuery, which has been proven so far a successful and productive query language for semi-structured data

  • JSON指针

    JSON 指针定义了一种字符串语法,用于标识 JavaScript 对象表示法 (JSON) 文档中的特定值。

  • 路径

    JSONPath 表达式始终以与 XPath 表达式与 XML 文档结合使用的相同方式引用 JSON 结构

  • JS路径

    JSON 的 JSPath 就像 XML 的 XPath。”

  • JSONiq

    JSONiq 背后的主要灵感来源是 XQuery,迄今为止,它已被证明是一种成功且高效的半结构化数据查询语言

回答by Milo S

Try JOLT. It is a JSON to JSON transformation library written in Java.

试试JOLT。它是一个用 Java 编写的 JSON 到 JSON 转换库。

It was created specifically because we did not want to play the "JSON -> XML -> XSLT -> XML -> JSON" game, and using a template for any sufficiently complex transform is unmaintainable.

它是专门创建的,因为我们不想玩“JSON -> XML -> XSLT -> XML -> JSON”游戏,并且使用模板进行任何足够复杂的转换都是不可维护的。

回答by 13ren

jq - lightweight and flexible command-line JSON processor

jq - 轻量级灵活的命令行 JSON 处理器

It's not template-based like XSLT, but more concise. e.g. to extract nameand addressfields into an array: [.name, .address]

它不像 XSLT 那样基于模板,但更简洁。例如,以提取nameaddress字段到一个数组:[.name, .address]

The tutorialwalks through an example of transforming Twitter's JSON API (and the manualhas many examples).

教程演练了一个转换 Twitter 的 JSON API 的示例(并且手册中有很多示例)。

回答by Chawathe Vipul S

XSLT supports JSON as seen at http://www.w3.org/TR/xslt-30/#json

XSLT 支持 JSON,见http://www.w3.org/TR/xslt-30/#json

XML uses angular brackets for delimiter tokens, JSON uses braces, square brackets, ... I. e. XML's fewer token recognition comparisons means it's optimized for declarative transformation, whereas more comparisons, being like switch statement, for speed reasons assume speculative branch prediction that imperative code in scripting languages is useful for. As direct consequence, for different mixes of semi-structured data, you may want to benchmark XSLT and javascript engines' performance as part of responsive pages. For negligible data payload, transformations might work just as well with JSON without XML serialization. W3's decision ought to be based on better analysis.

XML 使用尖括号作为分隔符,JSON 使用大括号、方括号......即。XML 较少的标记识别比较意味着它针对声明性转换进行了优化,而更多的比较(如 switch 语句)出于速度原因假设推测性分支预测,脚本语言中的命令式代码对其有用。作为直接结果,对于半结构化数据的不同组合,您可能希望将 XSLT 和 javascript 引擎的性能作为响应页面的一部分进行基准测试。对于可忽略不计的数据负载,转换可能与 JSON 一样好,无需 XML 序列化。W3 的决定应该基于更好的分析。

回答by Derek Curtis

I recently found a tool that I love for styling JSON: https://github.com/twigkit/tempo. Very easy tool to use--in my opinion, it is much easier to work with than XSLT--no need for XPATH queries.

我最近发现了一个我喜欢的 JSON 样式工具:https: //github.com/twigkit/tempo。非常容易使用的工具——在我看来,它比 XSLT 更容易使用——不需要 XPATH 查询。

回答by Chris

回答by YSharp

I wrote my own small library around this, recently, which tries to stay as close to

我最近围绕这个写了我自己的小图书馆,它试图保持尽可能接近

5.1 Processing Model (XSLT REC)https://www.w3.org/TR/xslt#section-Processing-Model

5.1 处理模型(XSLT REC)https://www.w3.org/TR/xslt#section-Processing-Model

as is possible (as I could anyway), in a few lines of JavaScript code.

尽可能(无论如何我都可以),在几行 JavaScript 代码中。

Here are a few not-completely-trivial examples of use...

这里有一些不完全是微不足道的使用示例......

1. JSON-to-some-markup:

1. JSON-to-some-markup:

Fiddle: https://jsfiddle.net/YSharpLanguage/kj9pk8oz/10

小提琴:https: //jsfiddle.net/YSharpLanguage/kj9pk8oz/10

(inspired by D.1 Document Example (XSLT REC)https://www.w3.org/TR/xslt#section-Document-Example)

(受D.1 文档示例 (XSLT REC) https://www.w3.org/TR/xslt#section-Document-Example启发)

where this:

在这里:

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));

... gives:

...给出:

<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>

and

2. JSON-to-JSON:

2. JSON 到 JSON:

Fiddle: https://jsfiddle.net/YSharpLanguage/ppfmmu15/10

小提琴:https: //jsfiddle.net/YSharpLanguage/ppfmmu15/10

where this:

在这里:

// (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));

... gives:

...给出:

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

3. XSLT vs. JavaScript:

3. XSLT 与 JavaScript:

A JavaScript equivalent of...

JavaScript 等价于...

XSLT 3.0 REC Section 14.4 Example: Grouping Nodes based on Common Values

XSLT 3.0 REC 第 14.4 节示例:基于通用值对节点进行分组

(at: http://jsfiddle.net/YSharpLanguage/8bqcd0ey/1)

(在:http: //jsfiddle.net/YSharpLanguage/8bqcd0ey/1

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

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

where...

在哪里...

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)
           });
    })
  );

... gives:

...给出:

<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 vs. JavaScript:

4. JSONiq 与 JavaScript:

A JavaScript equivalent of...

JavaScript 等价于...

JSONiq Use Cases Section 1.1.2. Grouping Queries for JSON

JSONiq 用例第 1.1.2 节。JSON 的分组查询

(at: https://jsfiddle.net/YSharpLanguage/hvo24hmk/3)

(在:https: //jsfiddle.net/YSharpLanguage/hvo24hmk/3

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

参见 http://jsoniq.org/docs/JSONiq-usecases/html-single/index.html#jsongrouping

where...

在哪里...

/*
  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()

... gives:

...给出:

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

It is also useful to overcome the limitations of JSONPath wrt. querying against the ancestor axis, as raised by this SO question(and certainly others).

克服 JSONPath wrt 的局限性也很有用。查询祖先轴,如this SO question(当然还有其他问题)提出。

E.g., how to get the discount of a grocery item knowing its brand id, in

例如,如何在知道其品牌 ID 的情况下获得杂货商品的折扣,

{
 "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"
     }
 ]
}

?

?

A possible solution is:

一个可能的解决方案是:

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);

... which gives:

... 这使:

Discount of #983: 20

'HTH,

'HTH,

回答by Rick

To say lack of tools suggest lack of need is just begging the question. The same could be applied to support for X or Y in Linux (Why bother developing quality drivers and/or games for such a minority OS? And why pay attention to an OS that big game and hardware companies don't develop for?). Probably the people who would need to use XSLT and JSON end up using a somewhat trivial workaround: Transforming JSON into XML. But that's not the optimal solution, is it?

说缺乏工具意味着缺乏需求只是在问这个问题。这同样适用于 Linux 中对 X 或 Y 的支持(为什么要为这样的少数操作系统开发高质量的驱动程序和/或游戏?为什么要关注大型游戏和硬件公司不为其开发的操作系统?)。可能需要使用 XSLT 和 JSON 的人最终使用了一个有点微不足道的解决方法:将 JSON 转换为 XML。但这不是最佳解决方案,是吗?

When you have a native JSON format and you want to edit it "wysywyg" in the browser, XSLT would be a more than adequate solution for the problem. Doing that with traditional javascript programming can become a pain in the arse.

当您拥有原生 JSON 格式并希望在浏览器中以“所见即所得”的方式对其进行编辑时,XSLT 将是解决该问题的一个绰绰有余的解决方案。使用传统的 javascript 编程来做到这一点可能会变得很麻烦。

In fact, I have implemented a "stone-age" approach to XSLT, using substring parsing to interpret some basic commands for javascript, like calling a template, process children, etc. Certainly implementing a transformation engine with a JSON object is much easier than implementing a full-fledged XML parser to parse the XSLT. Problem is, that to use XML templates to transform a JSON object you need to parse the XML of the templates.

事实上,我已经为 XSLT 实现了一种“石器时代”的方法,使用子字符串解析来解释 JavaScript 的一些基本命令,比如调用模板、处理子级等。当然,使用 JSON 对象实现转换引擎比实现一个成熟的 XML 解析器来解析 XSLT。问题是,要使用 XML 模板来转换 JSON 对象,您需要解析模板的 XML。

To tranform a JSON object with XML (or HTML, or text or whatever) you need to think carefully about the syntax and what special characters you need to use to identify the transformation commands. Otherwise you'll end up having to design a parser for your own custom templating language. Having walked through that path, I can tell you that it's not pretty.

要使用 XML(或 HTML、文本或其他)转换 JSON 对象,您需要仔细考虑语法以及需要使用哪些特殊字符来识别转换命令。否则,您最终将不得不为您自己的自定义模板语言设计一个解析器。走过那条路,我可以告诉你,它并不漂亮。

Update (Nov 12, 2010): After a couple of weeks working on my parser, I've been able to optimize it. Templates are parsed beforehand and commands are stored as JSON objects. Transformation rules are also JSON objects, while the template code is a mix of HTML and a homebrew syntax similar to shell code. I've been able to transform a complex JSON document into HTML to make a document editor. The code is around 1K lines for the editor (it's for a private project so I can't share it) and around 990 lines for the JSON transformation code (includes iteration commands, simple comparisons, template calling, variable saving and evaluation). I plan to release it under a MIT license. Drop me a mail if you want to get involved.

更新(2010 年 11 月 12 日):在我的解析器上工作几周后,我已经能够优化它。模板被预先解析,命令被存储为 JSON 对象。转换规则也是 JSON 对象,而模板代码是 HTML 和类似于 shell 代码的自制语法的混合。我已经能够将复杂的 JSON 文档转换为 HTML 以制作文档编辑器。编辑器的代码大约有 1000 行(它是用于私人项目,所以我无法共享它)和大约 990 行的 JSON 转换代码(包括迭代命令、简单比较、模板调用、变量保存和评估)。我计划在 MIT 许可下发布它。如果你想参与,给我发邮件。

回答by ColinE

There is now! I recently created a library, json-transforms, exactly for this purpose:

现在有!我最近创建了一个库json-transforms,正是为了这个目的:

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

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

It uses a combination of JSPath, a DSL modelled on XPath, and a recursive pattern matching approach, inspired directly by XSLT.

它结合了JSPath、基于 XPath 建模的 DSL 和直接受 XSLT 启发的递归模式匹配方法。

Here's a quick example. Given the following JSON object:

这是一个快速示例。给定以下 JSON 对象:

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 }
  ]
};

Here's a transformation:

这是一个转换:

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);

Which output the following:

输出如下:

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

This transform is composed of three rules. The first matches any automobile which is made by Honda, emitting an object with a Hondaproperty, then recursively matching. The second rule matches any object with a makerproperty, outputting the modeland yearproperties. The final is the identity transform that recursively matches.

此转换由三个规则组成。第一个匹配本田制造的任何汽车,发出具有Honda属性的对象,然后递归匹配。第二条规则匹配具有maker属性的任何对象,输出modelyear属性。最后是递归匹配的恒等变换。