JSON的XSLT等效项


411

是否有与JSON等效的XSLT?允许我像XSLT一样对JSON进行XML转换。


1
顺便说一句,这将是哪种语言/平台?
StaxMan

6
@StaxMan XSLT是一个在多种语言和平台上都有实际实现的标准,我的问题也针对类似的工作。
luvieere 2011年

36
为您的问题+1。许多人似乎忽略了XSLT或完全不喜欢XSLT,但这可能只是对XML详细信息的反应。确实,随着XML逐渐失宠,使用XSLT的机会越来越少了,这真是遗憾!JSON的等效XSLT很棒。
Nicolas Le Thierry d'Ennequin 2013年

10
@ NicolasLeThierryd'Ennequin同意。许多人讨厌XML,因此不赞成XSLT。工具的XML生态系统对Java开发人员也很沉重,这使更多的人流连忘返。但是在2000年代中期,我沉迷于XSLT,并且强大的功能在XML生态系统之外没有直接的等效功能。我会一个JSON相当于!
Zearin 2015年

Answers:


77

有趣的主意。在Google上进行的一些搜索产生了一些感兴趣的页面,包括:

希望这可以帮助。


10
是的,谢谢,这就是我想要的。遗憾的是该技术并不流行,JSON经常在REST风格的服务中用作返回格式,并且拥有一种实现对它的转换的标准方法会很好。
luvieere

8
这段代码使用string.eval()... :-(
dreftymac

链接唯一的答案
让-弗朗索瓦·法布尔

102

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

工具类

  1. XSLT

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

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

  2. q

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

  3. j

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

  4. 外汇

    命令行JSON处理工具

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

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

  6. 颠簸

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

  7. 格龙

    使JSON可以使用!gron将JSON转换为离散的赋值,以使其更易于根据需要进行grep并查看其绝对“路径”。它简化了对返回JSON大块但文档糟糕的API的探索。

  8. json

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

  9. json-e

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

  10. JSLT

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

  11. JSONata

    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 Last Commit 2017年3月13日

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

  15. jsonpath-object-transform最后提交2017年1月18日

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

  16. 装订最后提交2013年9月16日

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

眼镜:

  • JsonPointer

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

  • JsonPath

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

  • JSPath

    JSON的JSPath就像XML的XPath一样。”

  • JSONiq

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


2
感谢您的详细和有用的帖子。为了将单行json转换为可读形式,jq(列表中的nr.2)对我来说是最佳选择。再次感谢!
–primhunter

1
我经常使用json_pp进行漂亮的打印。它可用于许多发行版。
jschnasse

70

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

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


4
+9000:这是一个严肃的项目!哈萨 带有示例的在线演示极大地帮助您攀登了学习曲线:jolt-demo.appspot.com
kevinarpe

15

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

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

教程将介绍一个转换Twitter JSON API的示例(该手册包含许多示例)。


4
它更简洁,因为它的功能要少得多。
Ihe Onwuka 2015年

我没有找到如何在一个JSON树递归搜索一个给定的属性
丹尼尔

@Daniel是.. | .attr_name?您的寻找?(从stedolan.github.io/jq/manual/#RecursiveDescent:..
ankostis

1
可能不像XSLT那样强大,但是却非常有用,也没有像XSLT那样复杂
flq

15

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

XML使用尖括号作为定界符标记,JSON使用括号,方括号等。XML较少的令牌识别比较意味着它针对声明性转换进行了优化,而更多的比较(如switch语句)出于速度原因而假定推测性分支预测,而脚本语言中的命令性代码非常有用。直接的结果是,对于半结构化数据的不同混合,您可能希望将XSLT和javascript引擎的性能作为响应页面的一部分进行基准测试。对于可以忽略不计的数据有效负载,在不进行XML序列化的情况下,JSON转换也可以很好地工作。W3的决定应该基于更好的分析。


15

我最近找到了一个我喜欢的JSON样式设置工具:https : //github.com/twigkit/tempo。使用非常简单的工具-在我看来,它比XSLT使用起来容易得多-不需要XPATH查询。


9
如果转换的最终结果是HTML,则Tempo看起来很棒。但是,如果您只想将隐式结构重新排列为其他结构,而最终结果仍然是 JSON ,该怎么办。我仍然想要XPath的类似物,这样我就可以以实用的方式编写转换。
Toddius Zho 2013年

1
节奏非常有趣,的确谢谢。但是,您可以将xml发送到浏览器,并发送xslt(<?xsl-stylesheet>),浏览器会将xslt应用于xml,显示xml的定义视图,而无需任何其他代码。jsonT / tempo也应该如此。
Martin Meeser 2014年


11

要说缺乏工具表明缺乏需求,只是在问这个问题。同样的方法也可以用于支持Linux中的X或Y(为什么要为这样的少数操作系统而开发高质量的驱动程序和/或游戏?为什么还要关注大型游戏和硬件公司不为之开发的OS?)。可能需要使用XSLT和JSON的人最终会使用一些琐碎的变通方法:将JSON转换为XML。但这不是最佳解决方案,对吗?

当您具有本机JSON格式并且想要在浏览器中对其进行“ wysywyg”编辑时,XSLT将是解决该问题的充分解决方案。在传统的javascript编程中这样做可能会成为麻烦。

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

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

更新(2010年11月12日):在使用解析器几周之后,我已经能够对其进行优化。模板会预先解析,命令会存储为JSON对象。转换规则也是JSON对象,而模板代码是HTML和类似于Shell代码的自制语法的混合。我已经能够将复杂的JSON文档转换为HTML以创建文档编辑器。该代码的编辑器大约需要1K行(这是一个私人项目,所以我不能共享它),JSON转换代码大约990行(包括迭代命令,简单比较,模板调用,变量保存和评估)。我计划根据MIT许可证发布它。如果您想参与,请给我发邮件。


11

最近,我围绕着这个写了自己的小型图书馆,它试图保持与

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

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

这是一些使用不完全的例子...

1. JSON到某些标记:

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

(灵感来自D.1文档示例(XSLT REC) https://www.w3.org/TR/xslt#section-Document-Example

在这里:

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

...给出:

<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到JSON:

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

在这里:

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

...给出:

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

3. XSLT与JavaScript:

相当于...的JavaScript

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

(位于:http : //jsfiddle.net/YSharpLanguage/8bqcd0ey/1

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

哪里...

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

...给出:

<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与JavaScript:

相当于...的JavaScript

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

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

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

哪里...

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

...给出:

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

克服JSONPath wrt的限制也很有用。根据此SO问题(当然还有其他问题)提出的针对祖先轴的查询。

例如,如何在知道商品名称的情况下获得杂货的折扣

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

可能的解决方案是:

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

... 这使:

Discount of #983: 20

'HTH,


10

现在有!我最近为此创建了一个库json-transforms

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

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

这是一个简单的例子。给定以下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 }
  ]
};

这是一个转换:

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

输出以下内容:

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

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


9

作为对旧问题的又一个新答案,我建议您看一下DefiantJS。这不是一个XSLT 等同于JSON,它对JSON XSLT。文档的“模板化”部分包括以下示例:

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

我真的已经厌倦了那里大量的JavaScript模板引擎以及它们的所有内联HTML模板,不同的标记样式等,并决定建立一个小型库来为JSON数据结构实现XSLT格式化。无论如何,都不是火箭科学,它只是将JSON解析为XML,然后使用XSLT文档进行格式化。它的速度也很快,不及Chrome中的JavaScript模板引擎快,但在大多数其他浏览器中,它至少与大型数据结构的JS引擎替代品一样快。


4

我正在使用骆驼路线umarshal(xmljson)-> to(xlst)-> marshal(xmljson)。足够高效(尽管不是100%完美),但如果已经在使用Camel,就很简单。


3

JSONiq是这样的标准,而Zorba是开源C ++实现。JSONiq也可以看作XQuery,添加了JSON作为本机数据类型。



2

Yate(https://github.com/pasaran/yate)是在XSLT之后专门设计的,具有JPath(JS的自然XPath等效功能),可编译为JavaScript并具有相当的生产使用历史。它几乎没有文档记录,但通读样本和测试应该足够了。


2

JSLT非常类似于 XSLT的JSON。这是一种转换语言,您可以使用JSON语法编写输出的固定部分,然后插入表达式以计算要插入模板的值。

一个例子:

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

它是在Jackson之上的Java中实现的。


0

不太确定是否需要这样做,对我而言,缺乏工具表明缺乏需求。JSON最好作为对象处理(无论如何用JS完成),并且您通常使用对象本身的语言进行转换(Java用于从JSON创建的Java对象,与Perl,Python,Perl,c#,PHP等相同)上)。仅具有常规分配(或设置,获取),循环等。

我的意思是,XSLT只是另一种语言,需要这样做的一个原因是XML不是对象表示法,因此编程语言的对象不是完全适合的(分层xml模型与对象/结构之间的阻抗)。


在Facebook从XML转换为Json之后,我迫切需要这样的工具。
Joe Soul-bringer 2011年

您在想什么用例?是否能够以类似于将XML响应呈现为HTML的方式呈现JSON内容?还是有所不同?
StaxMan

我想知道与使用XSLT类型方法相比,以编程对象方式(带有循环,根据需要进行分支等)操纵JSON转换有多容易,尤其是在转换大规模JSON对象以及源JSON中的某些数据发生偏移的情况下在目标JSON中的某些节点上(不是简单地直接复制结构),并说出源JSON或目标JSON中的特定节点是JSON中对象数组的一部分,而其他JSON(源/目标)不是。
大卫,

缓和是非常主观的,因此我怀疑这很大程度上与习惯用法有关。
StaxMan

虽然绝对需要JSON转换,但您是正确的,JS基本上可以满足它。:-)但是您见过jq-轻巧灵活的命令行JSON处理器吗?特别是在JS不可用时。我要说的是,转换比JS更加容易和直观。例如,提取字段nameaddress,并将它们放入数组中:[.name, .address]
13ren

0

为什么不使用Data Coverter先生将JSON转换为XML ,使用XSLT转换它,然后再使用XSLT将其更改回JSON。


1
如果您想让自己的代码以良好的性能为您服务,那么这不是一个选择。
orad 2013年

0

有关使用纯JavaScript以及XSLT匹配表达式和递归模板背后的熟悉的声明式模式的方法的可行的涂鸦/概念验证,请参阅https://gist.github.com/brettz9/0e661b3093764f496e36

(对于JSON,可以采用类似的方法。)

请注意,该演示文稿还依赖JavaScript 1.8表达式闭包,以便于在Firefox中表达模板(至少直到可以实现方法的ES6简短形式)。

免责声明:这是我自己的代码。


0

很久以前,我为基于杰克逊的json处理框架编写了dom适配器。它使用nu.xom库。生成的dom树可与java xpath和xslt工具一起使用。我做出了一些非常简单的实现选择。例如,根节点始终被称为“根”,数组进入带有li子元素的ol节点(例如在html中),而其他所有元素只是具有原始值的子节点或另一个对象节点。

JsonXmlConverter.java

用法: JsonObject sampleJson = sampleJson(); org.w3c.dom.Document domNode = JsonXmlConverter.getW3cDocument(sampleJson, "root");


0

一种尚未给出的方法是使用解析器生成器在XSLT中创建一个解析器,该解析器解析JSON并生成XML输出。

ReX解析器生成器(http://www.bottlecaps.de/rex/)在XML会议上得到了很多提及,尽管该站点上没有完全记载,但可以在搜索中找到配方。


0

可以将XSLT与JSON结合使用。XPath(3.1)XSLT(3.0)和XQuery(3.1)的Verson 3以某种方式支持JSON。这似乎可以在Saxon的商业版本中获得,并且可能在某些时候包含在HE版本中。 https://www.saxonica.com/html/documentation/functions/fn/parse-json.html

--

我对替代解决方案的期望:

我希望能够输入JSON来获取匹配的数据集,并输出JSON或TEXT。

访问任意属性并评估值

支持条件逻辑

我希望转换脚本在该工具的外部,基于文本,最好是一种常用的语言。

潜在的替代方案?

我想知道SQL是否可以作为合适的替代方案。 https://docs.microsoft.com/zh-cn/sql/relational-databases/json/json-data-sql-server

如果替代工具可以处理JSON和XML,那就太好了 。https://docs.microsoft.com/zh-cn/sql/relational-databases/xml/openxml-sql-server

我尚未尝试将我使用的XSLT脚本转换为SQL,或者尚未完全评估此选项,但是希望尽快对此进行研究。到目前为止只有一些想法。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.