使用 XSLT 3.0 将 JSON 转换为 XML ,操作输出
Convert JSON to XML using XSLT 3.0 , manipulate the output
我想将 JSON 数据转换为 xml。为此,我使用函数 json-to-xml。
JSON
{
"example": {
"items": [
{
"_links": {
"self": {
"href": "xxx"
}
},
"test": "123",
"nummer": "456",
"parent": null,
"category": [
"test"
],
"select": true,
"values": {
"abc": [
{
"test": null,
"data": 2
}
]
},
"cpu": {
"1": {
"cpus": []
},
"3": {
"cpus": []
},
"4": {
"cpus": [
"cpu1"]
},
"5": {
"cpus": [
"cpu6"
]
}
}
},
{
"_links": {
"self": {
"href": "xxx"
}
},
"test": "789",
"nummer": "4110",
"parent": null,
"category": [
"test"
],
"select": true,
"values": {
"abc": [
{
"test": null,
"data": 2
}
]
},
"cpu": {
"1": {
"cpus": []
},
"3": {
"cpus": []
},
"4": {
"cpus": [
"cpu3"
]
},
"5": {
"cpus": [
"cpu4",
"cpu5"
]
}
}
}
]
}
}
我使用的xslt:
<xsl:param name="input" select="'url json'"/>
<xsl:template name="initial">
<xsl:apply-templates select="json-to-xml(unparsed-text($input))" mode="copy"/>
</xsl:template>
<xsl:template match="node() | @*" mode="copy">
<xsl:copy>
<xsl:apply-templates select="node() | @*" mode="copy"/>
</xsl:copy>
</xsl:template>
结果有这样的结构:
<map xmlns="http://www.w3.org/2005/xpath-functions">
<map key="example">
<array key="items">
<map>
<map key="_links">
<map key="self">
<string key="href">xxx</string>
</map>
</map>
<string key="test">123</string>
<string key="nummer">456</string>
<null key="parent"/>
<array key="category">
<string>test</string>
</array>
<boolean key="select">true</boolean>
<map key="values">
<array key="abc">
<map>
<null key="test"/>
<number key="data">2</number>
</map>
</array>
</map>
<map key="cpu">
<map key="1">
<array key="cpus"/>
</map>
<map key="3">
<array key="cpus"/>
</map>
<map key="4">
<array key="cpus">
<string>cpu1</string>
</array>
</map>
<map key="5">
<array key="cpus">
<string>cpu6</string>
</array>
</map>
</map>
</map>
<map>
<map key="_links">
<map key="self">
<string key="href">xxx</string>
</map>
</map>
<string key="test">789</string>
<string key="nummer">4110</string>
<null key="parent"/>
<array key="category">
<string>test</string>
</array>
<boolean key="select">true</boolean>
<map key="values">
<array key="abc">
<map>
<null key="test"/>
<number key="data">2</number>
</map>
</array>
</map>
<map key="cpu">
<map key="1">
<array key="cpus"/>
</map>
<map key="3">
<array key="cpus"/>
</map>
<map key="4">
<array key="cpus">
<string>cpu3</string>
</array>
</map>
<map key="5">
<array key="cpus">
<string>cpu4</string>
<string>cpu5</string>
</array>
</map>
</map>
</map>
</array>
</map>
</map>
这就是我想要的。
<?xml version="1.0" encoding="UTF-8"?>
<example>
<items>
<_links>
<self>
<href>xxx</href>
</self>
</_links>
<test>123</test>
<nummer>456</nummer>
<parent>null</parent>
<category>test</category>
<select>true</select>
<values>
<abc>
<test>null</test>
<data>2</data>
</abc>
</values>
<cpu>
<_1></_1>
<_3></_3>
<_4>
<cpus>cpu1</cpus>
</_4>
<_5>
<cpus>cpu6</cpus>
</_5>
</cpu>
</items>
<items>
<_links>
<self>
<href>xxx</href>
</self>
</_links>
<test>789</test>
<nummer>4110</nummer>
<parent>null</parent>
<category>test</category>
<select>true</select>
<values>
<abc>
<test>null</test>
<data>2</data>
</abc>
</values>
<cpu>
<_1></_1>
<_3></_3>
<_4>
<cpus>cpu3</cpus>
</_4>
<_5>
<cpus>cpu4</cpus>
<cpus>cpu5</cpus>
</_5>
</cpu>
</items>
</example>
我想删除关键属性。另外元素 "items" 应该是 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="xs"
version="3.0">
<xsl:output method="xml" omit-xml-declaration="no" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*[@key]">
<xsl:element name="{@key}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
将模式设置为仅复制文本,并添加模板以将具有键的元素转换为该键的元素,如果键不是 QName,则进行一些错误更正:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="#all">
<xsl:param name="input" select="'input.json'"/>
<xsl:output indent="yes"/>
<xsl:function name="mf:element-name" as="xs:QName">
<xsl:param name="key" as="xs:string"/>
<xsl:try select="xs:QName($key)">
<xsl:catch select="xs:QName('_' || $key)"/>
</xsl:try>
</xsl:function>
<xsl:mode name="strip" on-no-match="text-only-copy"/>
<xsl:template name="xsl:initial-template" match="/">
<xsl:apply-templates select="json-to-xml(unparsed-text($input))" mode="strip"/>
</xsl:template>
<xsl:template match="*[@key]" mode="strip">
<xsl:element name="{mf:element-name(@key)}">
<xsl:apply-templates mode="#current"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
我想将 JSON 数据转换为 xml。为此,我使用函数 json-to-xml。
JSON
{
"example": {
"items": [
{
"_links": {
"self": {
"href": "xxx"
}
},
"test": "123",
"nummer": "456",
"parent": null,
"category": [
"test"
],
"select": true,
"values": {
"abc": [
{
"test": null,
"data": 2
}
]
},
"cpu": {
"1": {
"cpus": []
},
"3": {
"cpus": []
},
"4": {
"cpus": [
"cpu1"]
},
"5": {
"cpus": [
"cpu6"
]
}
}
},
{
"_links": {
"self": {
"href": "xxx"
}
},
"test": "789",
"nummer": "4110",
"parent": null,
"category": [
"test"
],
"select": true,
"values": {
"abc": [
{
"test": null,
"data": 2
}
]
},
"cpu": {
"1": {
"cpus": []
},
"3": {
"cpus": []
},
"4": {
"cpus": [
"cpu3"
]
},
"5": {
"cpus": [
"cpu4",
"cpu5"
]
}
}
}
]
}
}
我使用的xslt:
<xsl:param name="input" select="'url json'"/>
<xsl:template name="initial">
<xsl:apply-templates select="json-to-xml(unparsed-text($input))" mode="copy"/>
</xsl:template>
<xsl:template match="node() | @*" mode="copy">
<xsl:copy>
<xsl:apply-templates select="node() | @*" mode="copy"/>
</xsl:copy>
</xsl:template>
结果有这样的结构:
<map xmlns="http://www.w3.org/2005/xpath-functions">
<map key="example">
<array key="items">
<map>
<map key="_links">
<map key="self">
<string key="href">xxx</string>
</map>
</map>
<string key="test">123</string>
<string key="nummer">456</string>
<null key="parent"/>
<array key="category">
<string>test</string>
</array>
<boolean key="select">true</boolean>
<map key="values">
<array key="abc">
<map>
<null key="test"/>
<number key="data">2</number>
</map>
</array>
</map>
<map key="cpu">
<map key="1">
<array key="cpus"/>
</map>
<map key="3">
<array key="cpus"/>
</map>
<map key="4">
<array key="cpus">
<string>cpu1</string>
</array>
</map>
<map key="5">
<array key="cpus">
<string>cpu6</string>
</array>
</map>
</map>
</map>
<map>
<map key="_links">
<map key="self">
<string key="href">xxx</string>
</map>
</map>
<string key="test">789</string>
<string key="nummer">4110</string>
<null key="parent"/>
<array key="category">
<string>test</string>
</array>
<boolean key="select">true</boolean>
<map key="values">
<array key="abc">
<map>
<null key="test"/>
<number key="data">2</number>
</map>
</array>
</map>
<map key="cpu">
<map key="1">
<array key="cpus"/>
</map>
<map key="3">
<array key="cpus"/>
</map>
<map key="4">
<array key="cpus">
<string>cpu3</string>
</array>
</map>
<map key="5">
<array key="cpus">
<string>cpu4</string>
<string>cpu5</string>
</array>
</map>
</map>
</map>
</array>
</map>
</map>
这就是我想要的。
<?xml version="1.0" encoding="UTF-8"?>
<example>
<items>
<_links>
<self>
<href>xxx</href>
</self>
</_links>
<test>123</test>
<nummer>456</nummer>
<parent>null</parent>
<category>test</category>
<select>true</select>
<values>
<abc>
<test>null</test>
<data>2</data>
</abc>
</values>
<cpu>
<_1></_1>
<_3></_3>
<_4>
<cpus>cpu1</cpus>
</_4>
<_5>
<cpus>cpu6</cpus>
</_5>
</cpu>
</items>
<items>
<_links>
<self>
<href>xxx</href>
</self>
</_links>
<test>789</test>
<nummer>4110</nummer>
<parent>null</parent>
<category>test</category>
<select>true</select>
<values>
<abc>
<test>null</test>
<data>2</data>
</abc>
</values>
<cpu>
<_1></_1>
<_3></_3>
<_4>
<cpus>cpu3</cpus>
</_4>
<_5>
<cpus>cpu4</cpus>
<cpus>cpu5</cpus>
</_5>
</cpu>
</items>
</example>
我想删除关键属性。另外元素 "items" 应该是 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="xs"
version="3.0">
<xsl:output method="xml" omit-xml-declaration="no" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*[@key]">
<xsl:element name="{@key}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
将模式设置为仅复制文本,并添加模板以将具有键的元素转换为该键的元素,如果键不是 QName,则进行一些错误更正:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="#all">
<xsl:param name="input" select="'input.json'"/>
<xsl:output indent="yes"/>
<xsl:function name="mf:element-name" as="xs:QName">
<xsl:param name="key" as="xs:string"/>
<xsl:try select="xs:QName($key)">
<xsl:catch select="xs:QName('_' || $key)"/>
</xsl:try>
</xsl:function>
<xsl:mode name="strip" on-no-match="text-only-copy"/>
<xsl:template name="xsl:initial-template" match="/">
<xsl:apply-templates select="json-to-xml(unparsed-text($input))" mode="strip"/>
</xsl:template>
<xsl:template match="*[@key]" mode="strip">
<xsl:element name="{mf:element-name(@key)}">
<xsl:apply-templates mode="#current"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>