在一些帮助下,我放置了以下脚本,该脚本将JSON文件作为参数并将其输出为XML。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:param name="json" as="xs:string">
[
{
"ID":"DWL",
"profiles":[
{
"firstName":"Contact",
"lastName":"Sample",
"emailAddresses":[
{
"emailAddress":"inactive@mailinator.com"
}
]
}
]
},
{
"ID":"DWLK",
"profiles":[
{
"firstName":"Contact",
"lastName":"Sample",
"emailAddresses":[
{
"emailAddress":"sampltest@mailinator.com",
"primary":true
}
]
}
]
}
]
</xsl:param>
<xsl:template match="/" name="xsl:initial-template">
<xsl:sequence select="json-to-xml($json)"/>
</xsl:template>
</xsl:stylesheet>
我需要修改脚本以提取ID profiles.FirstName
和profiles.emailAddresses
,并添加一个额外的静态字段origin
。最终输出应为以下内容:
[
{
"ID":"DWL",
"origin":"static",
"profiles":[
{
"firstName":"Contact",
"emailAddresses":[
{
"emailAddress":"sample@mailinator.com"
}
]
}
]
},
{
"ID":"DWLK",
"origin":"static",
"profiles":[
{
"firstName":"Contact",
"emailAddresses":[
{
"emailAddress":"sampltest@mailinator.com",
"primary":true
}
]
}
]
}
]
答案 0 :(得分:2)
基本上,有两种使用XSLT 3.0处理JSON的方式:您可以将其作为映射和数组来处理,也可以将其转换为XML(然后再次转换为XML)。在XML Prague 2016上的一篇论文(可在http://www.saxonica.com/papers/xmlprague-2016mhk.pdf上),我探索了几个用例,将这两种技术进行了比较,并且我通常发现向XML的转换和向后转换都更加容易,主要原因是XML的模式匹配机制结构比映射和数组的模式匹配要灵活得多(这反过来是因为XML树允许您向上导航以检查上下文,而映射和数组则不允许)。
使用这种方法,您将转换为XML,然后对XML进行标准转换,如下所示:
<xsl:mode name="add-origin" on-no-match="shallow-copy"/>
<xsl:template match="fn:map[*[@key='ID']]" mode="add-origin">
<xsl:copy>
<xsl:copy-of select="@*"/>
<fn:string key="origin">static</fn:string>
<xsl:copy-of select="node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/" name="xsl:initial-template">
<xsl:variable name="converted">
<xsl:apply-templates select="json-to-xml($json)" mode="add-origin"/>
</xsl:variable>
<xsl:sequence select="xml-to-json($converted)"/>
</xsl:template>
您提到从输入中“提取”一些信息;我不确定我是否理解该要求,但是可以使用查找运算符“?”从parse-json()传递的映射数组表示中很容易地从JSON提取信息。例如,您可以使用$json?*?ID
获取所有ID值,或者可以使用$json?*[?ID='JWL']?profiles?1?firstName
获取ID为JWL的人的名字。
答案 1 :(得分:0)
使用<xsl:sequence select="json-to-xml($json)"/>
进行的第一次转换显示在https://xsltfiddle.liberty-development.net/bnnZWD/5上,并给出了XML
<array xmlns="http://www.w3.org/2005/xpath-functions">
<map>
<string key="ID">DWL</string>
<array key="profiles">
<map>
<string key="firstName">Contact</string>
<string key="lastName">Sample</string>
<array key="emailAddresses">
<map>
<string key="emailAddress">inactive@mailinator.com</string>
</map>
</array>
</map>
</array>
</map>
<map>
<string key="ID">DWLK</string>
<array key="profiles">
<map>
<string key="firstName">Contact</string>
<string key="lastName">Sample</string>
<array key="emailAddresses">
<map>
<string key="emailAddress">sampltest@mailinator.com</string>
<boolean key="primary">true</boolean>
</map>
</array>
</map>
</array>
</map>
</array>
如果您将其用作中间结果并通过一些模板(https://xsltfiddle.liberty-development.net/bnnZWD/6)进行推送
<xsl:template match="/" name="xsl:initial-template">
<xsl:variable name="json-xml" select="json-to-xml($json)"/>
<xsl:apply-templates select="$json-xml/node()"/>
</xsl:template>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="string[@key = 'ID']">
<xsl:next-match/>
<string key="origin">static</string>
</xsl:template>
<xsl:template match="string[@key = 'lastName']"/>
要获得的更改:
<array xmlns="http://www.w3.org/2005/xpath-functions">
<map>
<string key="ID">DWL</string>
<string key="origin">static</string>
<array key="profiles">
<map>
<string key="firstName">Contact</string>
<array key="emailAddresses">
<map>
<string key="emailAddress">inactive@mailinator.com</string>
</map>
</array>
</map>
</array>
</map>
<map>
<string key="ID">DWLK</string>
<string key="origin">static</string>
<array key="profiles">
<map>
<string key="firstName">Contact</string>
<array key="emailAddresses">
<map>
<string key="emailAddress">sampltest@mailinator.com</string>
<boolean key="primary">true</boolean>
</map>
</array>
</map>
</array>
</map>
</array>
然后您可以使用xml-to-json
:(https://xsltfiddle.liberty-development.net/bnnZWD/7)将转换后的XML转换回JSON
<xsl:output method="text"/>
<xsl:template match="/" name="xsl:initial-template">
<xsl:variable name="json-xml" select="json-to-xml($json)"/>
<xsl:variable name="transformed-json-xml">
<xsl:apply-templates select="$json-xml/node()"/>
</xsl:variable>
<xsl:value-of select="xml-to-json($transformed-json-xml, map { 'indent' : true() })"/>
</xsl:template>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="string[@key = 'ID']">
<xsl:next-match/>
<string key="origin">static</string>
</xsl:template>
<xsl:template match="string[@key = 'lastName']"/>
并使用Saxon 9.8获得输出
[
{ "ID" : "DWL",
"origin" : "static",
"profiles" :
[
{ "firstName" : "Contact",
"emailAddresses" :
[
{ "emailAddress" : "inactive@mailinator.com" } ] } ] },
{ "ID" : "DWLK",
"origin" : "static",
"profiles" :
[
{ "firstName" : "Contact",
"emailAddresses" :
[
{ "emailAddress" : "sampltest@mailinator.com",
"primary" : true } ] } ] } ]
清理中间步骤,可以将代码缩短为
<xsl:output method="text"/>
<xsl:template match="/" name="xsl:initial-template">
<xsl:variable name="transformed-json-xml">
<xsl:apply-templates select="json-to-xml($json)/node()"/>
</xsl:variable>
<xsl:value-of select="xml-to-json($transformed-json-xml, map { 'indent' : true() })"/>
</xsl:template>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="string[@key = 'ID']">
<xsl:next-match/>
<string key="origin">static</string>
</xsl:template>
<xsl:template match="string[@key = 'lastName']"/>
https://xsltfiddle.liberty-development.net/bnnZWD/9
当然,除了使用带有JSON字符串内容的参数外,您还可以使用unparsed-text
从JSON文件中加载,例如<xsl:param name="json" select="unparsed-text('file.json')"/>
。