JSON的XSLT等效方法

518

是否有针对JSON的XSLT等效工具? 让我可以像XSLT将XML转换一样在JSON上进行转换。


9
XSLT是一种标准,许多语言和平台都有实际的实现,我的问题是针对类似的努力。 - luvieere
55
对于你的问题点赞。许多人似乎忽视或者纯粹不喜欢XSLT,但这可能只是对XML冗长性的反应。随着XML逐渐失宠,使用XSLT的机会也越来越少,这很遗憾!如果有一个JSON的等效XSLT将是很棒的。 - Nicolas Le Thierry d'Ennequin
13
@NicolasLeThierryd'Ennequin 同意。很多人讨厌XML,因此忽视了XSLT。XML工具生态系统也以Java开发人员为主,这使更多人望而却步。但在2000年代中期我非常熟悉XSLT,在XML生态系统之外没有直接等效的强大功能。我希望有一个JSON的等效物! - Zearin
1
@NicolasLeThierryd'Ennequin:请查看以下链接:https://jsfiddle.net/YSharpLanguage/kj9pk8oz/10或者https://jsfiddle.net/YSharpLanguage/ppfmmu15/10或者https://jsfiddle.net/YSharpLanguage/hvo24hmk/3 - YSharp
4
我强烈反对关闭这个答案。简单的改写就足够了:“如何使用声明式的方式重构JSON?” - Gregory Higley
显示剩余10条评论
24个回答

9
现在有了一个库叫做json-transforms,专门用于这个目的:https://github.com/ColinEberhardt/json-transforms。它使用基于XPath的DSL模型JSPath和递归模式匹配方法,直接启发自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 属性。最后一个是递归匹配的身份转换。

5

我已经非常厌倦了市面上众多的JavaScript模板引擎,它们的内联HTML模板、不同的标记样式等等,于是决定构建一个小型库,使得JSON数据结构可以使用XSLT格式化。这并不需要什么高深的技术--只是将JSON解析为XML,并使用XSLT文档进行格式化。它速度也很快,在Chrome浏览器中可能没有JavaScript模板引擎那么快,但对于更大的数据结构,在大多数其他浏览器中它至少与JavaScript引擎替代方案的速度相当。


4

JSLT非常接近于JSON等效的XSLT。这是一种转换语言,您可以在其中使用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上实现的。


4
我正在使用Camel路由,将XML/JSON解组(unmarshal) -> 转换(xlst) -> 编组(marshal)进行操作。这种方法非常高效(虽然不是100%完美),而且简单易懂,如果您已经在使用Camel的话。

3

JSONiq 是一种标准,Zorba 是一个开源的 C++ 实现。JSONiq 可以被看作是在 XQuery 中添加了 JSON 作为一种本地数据类型。


2

1

Yate(https://github.com/pasaran/yate)是专门为XSLT设计的,具有JPath功能(JS的自然XPath等效功能),编译成JavaScript并且有相当长时间的生产使用历史。它几乎没有文档记录,但是阅读示例和测试应该足够了解。


0

为了展示一种利用纯JavaScript以及XSLT匹配表达式和递归模板背后熟悉的声明式模式的方法的工作涂鸦/概念证明,请参见https://gist.github.com/brettz9/0e661b3093764f496e36

(JSON也可以采用类似的方法。)

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

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


0
为什么不使用Mr. Data Converter将JSON转换为XML,然后使用XSLT进行转换,最后再使用相同的工具将其转换回JSON呢?

1
如果你想让你的代码以良好的性能为你完成这项任务,那么这不是一个选项。 - orad

0
我很久以前为我的基于Jackson的JSON处理框架编写了一个DOM适配器。它使用nu.xom库。生成的DOM树可以与Java XPath和XSLT工具一起使用。我做了一些相当直接的实现选择。例如,根节点始终称为“root”,数组进入带有li子元素的ol节点(就像在HTML中一样),而其他所有内容都只是具有原始值或另一个对象节点的子节点。

JsonXmlConverter.java

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接