使用 XSLT 3.0 进行转换 XML
Using XSLT 3.0 to transform XML
我想使用 XSLT 将一些 XML 转换为 JSON。
XML 如下所示:
<?xml version="1.0" ?>
<CoronaInfections>
<Countries>
<item>
<Country>Afghanistan</Country>
<CountryCode>AF</CountryCode>
<Slug>afghanistan</Slug>
<NewConfirmed>542</NewConfirmed>
<TotalConfirmed>21459</TotalConfirmed>
<NewDeaths>15</NewDeaths>
<TotalDeaths>384</TotalDeaths>
<NewRecovered>480</NewRecovered>
<TotalRecovered>2651</TotalRecovered>
<Date>2020-06-10T10:06:56Z</Date>
<Lat>33.0000</Lat>
<Lng>65.0000</Lng>
</item>
<item>
<Country>Albania</Country>
<CountryCode>AL</CountryCode>
<Slug>albania</Slug>
<NewConfirmed>36</NewConfirmed>
<TotalConfirmed>1299</TotalConfirmed>
<NewDeaths>0</NewDeaths>
<TotalDeaths>34</TotalDeaths>
<NewRecovered>15</NewRecovered>
<TotalRecovered>960</TotalRecovered>
<Date>2020-06-10T10:06:56Z</Date>
<Lat>41.0000</Lat>
<Lng>20.0000</Lng>
</item>
<item>
<Country>Algeria</Country>
<CountryCode>DZ</CountryCode>
<Slug>algeria</Slug>
<NewConfirmed>117</NewConfirmed>
<TotalConfirmed>10382</TotalConfirmed>
<NewDeaths>9</NewDeaths>
<TotalDeaths>724</TotalDeaths>
<NewRecovered>152</NewRecovered>
<TotalRecovered>6951</TotalRecovered>
<Date>2020-06-10T10:06:56Z</Date>
<Lat>28.0000</Lat>
<Lng>3.0000</Lng>
</item>
</Countries>
</CoronaInfections>
我希望 JSON 如下所示:
{ "type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"radius": 1.0841103742476927,
"id": "AF",
"countryName": "Afghanistan"
},
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [33.0000, 65.0000]
},
},
{
"type": "Feature",
"properties": {
"radius": 0.06562558255966042,
"id": "AL",
"countryName": "Albania"
},
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [41.0000, 20.0000]
},
},
]
}
推荐的方法是什么?
我已经有了一种方法,但看起来不太好,因为它只适用于 xslt 1.0(我认为)和文本块。
看这里:https://xsltfiddle.liberty-development.net/naZYrpy/1
我更喜欢使用 xslt 3.0 和 xml-to-json 函数的更有效方式,但似乎无法添加额外的 json 对象。
更多示例:
1. 不工作:https://xsltfiddle.liberty-development.net/pNmCzsA
提前致谢:-)
如果您想直接使用 XPath 3.1 创建 XDM 映射和数组以序列化为 JSON,请使用
<xsl:sequence
select="map { 'type' : 'FeatureCollection',
'Features' : array {
//item ! (
map {
'type' : 'Feature',
'properties' : map {
'radius' : TotalConfirmed div $max * 100,
'id' : data(CountryCode),
'countryName' : data(Country)
}
},
map {
'type' : 'Feature',
'geometry' : map {
'type' : 'Point',
'coordinates' : [number(Lat), number(Lng)]
}
}
)}
}"/>
https://xsltfiddle.liberty-development.net/a9HjZi
请注意,像 Javascript 对象这样的 XDM 映射没有任何有序的属性集合,因此您可以通过这种方式定义序列化顺序,Saxon 9 和 10 的商业版为此提供了扩展。
或者您需要将输入 XML 转换为 XML 格式 xml-to-json
函数 exepcts,它将 XML 输入中元素的顺序保留为JSON序列化的输出顺序:
<?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"
xmlns="http://www.w3.org/2005/xpath-functions"
exclude-result-prefixes="#all"
expand-text="yes"
version="3.0">
<xsl:output method="text"/>
<xsl:variable name="max" select="max(//item/*[starts-with(local-name(), 'TotalConfirmed')]/xs:integer(.))"/>
<xsl:template match="/">
<xsl:variable name="xml-to-json-input">
<map>
<string key="type">FeatureCollection</string>
<array key="features">
<xsl:apply-templates select="//item"/>
</array>
</map>
</xsl:variable>
<xsl:value-of select="xml-to-json($xml-to-json-input, map { 'indent' : true() })"/>
</xsl:template>
<xsl:template match="item">
<map>
<string key="type">Feature</string>
<map key="properties">
<number key="radius">{TotalConfirmed div $max * 100}</number>
<string key="id">{CountryCode}</string>
<string key="countryName">{Country}</string>
</map>
</map>
<map>
<string key="type">Feature</string>
<map key="geometry">
<string key="type">Point</string>
<array key="coordinates">
<number>{number(Lat)}</number>
<number>{number(Lng)}</number>
</array>
</map>
</map>
</xsl:template>
</xsl:stylesheet>
我想使用 XSLT 将一些 XML 转换为 JSON。 XML 如下所示:
<?xml version="1.0" ?>
<CoronaInfections>
<Countries>
<item>
<Country>Afghanistan</Country>
<CountryCode>AF</CountryCode>
<Slug>afghanistan</Slug>
<NewConfirmed>542</NewConfirmed>
<TotalConfirmed>21459</TotalConfirmed>
<NewDeaths>15</NewDeaths>
<TotalDeaths>384</TotalDeaths>
<NewRecovered>480</NewRecovered>
<TotalRecovered>2651</TotalRecovered>
<Date>2020-06-10T10:06:56Z</Date>
<Lat>33.0000</Lat>
<Lng>65.0000</Lng>
</item>
<item>
<Country>Albania</Country>
<CountryCode>AL</CountryCode>
<Slug>albania</Slug>
<NewConfirmed>36</NewConfirmed>
<TotalConfirmed>1299</TotalConfirmed>
<NewDeaths>0</NewDeaths>
<TotalDeaths>34</TotalDeaths>
<NewRecovered>15</NewRecovered>
<TotalRecovered>960</TotalRecovered>
<Date>2020-06-10T10:06:56Z</Date>
<Lat>41.0000</Lat>
<Lng>20.0000</Lng>
</item>
<item>
<Country>Algeria</Country>
<CountryCode>DZ</CountryCode>
<Slug>algeria</Slug>
<NewConfirmed>117</NewConfirmed>
<TotalConfirmed>10382</TotalConfirmed>
<NewDeaths>9</NewDeaths>
<TotalDeaths>724</TotalDeaths>
<NewRecovered>152</NewRecovered>
<TotalRecovered>6951</TotalRecovered>
<Date>2020-06-10T10:06:56Z</Date>
<Lat>28.0000</Lat>
<Lng>3.0000</Lng>
</item>
</Countries>
</CoronaInfections>
我希望 JSON 如下所示:
{ "type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"radius": 1.0841103742476927,
"id": "AF",
"countryName": "Afghanistan"
},
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [33.0000, 65.0000]
},
},
{
"type": "Feature",
"properties": {
"radius": 0.06562558255966042,
"id": "AL",
"countryName": "Albania"
},
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [41.0000, 20.0000]
},
},
]
}
推荐的方法是什么?
我已经有了一种方法,但看起来不太好,因为它只适用于 xslt 1.0(我认为)和文本块。 看这里:https://xsltfiddle.liberty-development.net/naZYrpy/1
我更喜欢使用 xslt 3.0 和 xml-to-json 函数的更有效方式,但似乎无法添加额外的 json 对象。
更多示例: 1. 不工作:https://xsltfiddle.liberty-development.net/pNmCzsA
提前致谢:-)
如果您想直接使用 XPath 3.1 创建 XDM 映射和数组以序列化为 JSON,请使用
<xsl:sequence
select="map { 'type' : 'FeatureCollection',
'Features' : array {
//item ! (
map {
'type' : 'Feature',
'properties' : map {
'radius' : TotalConfirmed div $max * 100,
'id' : data(CountryCode),
'countryName' : data(Country)
}
},
map {
'type' : 'Feature',
'geometry' : map {
'type' : 'Point',
'coordinates' : [number(Lat), number(Lng)]
}
}
)}
}"/>
https://xsltfiddle.liberty-development.net/a9HjZi
请注意,像 Javascript 对象这样的 XDM 映射没有任何有序的属性集合,因此您可以通过这种方式定义序列化顺序,Saxon 9 和 10 的商业版为此提供了扩展。
或者您需要将输入 XML 转换为 XML 格式 xml-to-json
函数 exepcts,它将 XML 输入中元素的顺序保留为JSON序列化的输出顺序:
<?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"
xmlns="http://www.w3.org/2005/xpath-functions"
exclude-result-prefixes="#all"
expand-text="yes"
version="3.0">
<xsl:output method="text"/>
<xsl:variable name="max" select="max(//item/*[starts-with(local-name(), 'TotalConfirmed')]/xs:integer(.))"/>
<xsl:template match="/">
<xsl:variable name="xml-to-json-input">
<map>
<string key="type">FeatureCollection</string>
<array key="features">
<xsl:apply-templates select="//item"/>
</array>
</map>
</xsl:variable>
<xsl:value-of select="xml-to-json($xml-to-json-input, map { 'indent' : true() })"/>
</xsl:template>
<xsl:template match="item">
<map>
<string key="type">Feature</string>
<map key="properties">
<number key="radius">{TotalConfirmed div $max * 100}</number>
<string key="id">{CountryCode}</string>
<string key="countryName">{Country}</string>
</map>
</map>
<map>
<string key="type">Feature</string>
<map key="geometry">
<string key="type">Point</string>
<array key="coordinates">
<number>{number(Lat)}</number>
<number>{number(Lng)}</number>
</array>
</map>
</map>
</xsl:template>
</xsl:stylesheet>