提问人:Ven 提问时间:8/31/2023 更新时间:8/31/2023 访问量:89
使用 XSLT1.0 将 JSON 转换为 XML
Conversion of JSON to XML using XSLT1.0
问:
我想使用 XSLT1.0 将 XML 的一部分 JSON 转换为 XML 结构(原因是我们的应用程序仅支持 XSLT1.0 版本)。 有人可以检查并让我知道吗?谢谢
XML(带JSON):在下面的例子中,在代码标签下,有要转换的JSON。
<root>
<root>
<order>131as</order>
<type>se134</type>
<num>15643</num>
<curr>USD</curr>
<code>{"desc":"Testing123","city":"Dubai","auth":"author","store":[{"quantity":1,"amount":2.00},{"quantity":100,"amount":-8.33},{"quantity":300,"amount":-15.00}]}</code>
</root>
<root>
<order>231as</order>
<type>se134</type>
<num>15643</num>
<curr>AED</curr>
<code>{"desc":"testdesc","city":"SHarjah","auth":"Mohammad","amount":20.00,"shop":"test","store":[{"quantity":1,"amount":10.00},{"quantity":100,"amount":98.33},{"quantity":300,"amount":-1.00}]}</code>
</root>
<root>
<order>331as</order>
<type>se134</type>
<num>15643</num>
<curr>SAR</curr>
<code/>
</root>
<root>
<order>431as</order>
<type>se134</type>
<num>15643</num>
<curr>USD</curr>
<code/>
</root>
<root>
<order>531as</order>
<type>Tse134</type>
<num>15643</num>
<curr>AED</curr>
<code>{"desc":"testdesc","city":"Abudabhi","auth":"Mr.121","amount":10.00,"shop":"testa","store":[{"quantity":71,"amount":10.00},{"quantity":100,"amount":95.33},{"quantity":300,"amount":-8.00}]}</code>
</root>
预期产量 :
<root>
<root>
<order>131as</order>
<type>se134</type>
<num>15643</num>
<curr>USD</curr>
<code>
<root>
<amount>10.0</amount>
<auth>Mr.121</auth>
<city>Abudabhi</city>
<desc>testdesc</desc>
<shop>testa</shop>
<store>
<element>
<amount>10.0</amount>
<quantity>71</quantity>
</element>
<element>
<amount>95.33</amount>
<quantity>100</quantity>
</element>
<element>
<amount>-8.0</amount>
<quantity>300</quantity>
</element>
</store>
</root>
</code>
</root>
<root>
<order>231as</order>
<type>se134</type>
<num>15643</num>
<curr>AED</curr>
<code>
<root>
<amount>20.0</amount>
<auth>Mohammad</auth>
<city>SHarjah</city>
<desc>testdesc</desc>
<shop>test</shop>
<store>
<element>
<amount>10.0</amount>
<quantity>1</quantity>
</element>
<element>
<amount>98.33</amount>
<quantity>100</quantity>
</element>
<element>
<amount>-1.0</amount>
<quantity>300</quantity>
</element>
</store>
</root>
</code>
</root>
<root>
<order>331as</order>
<type>se134</type>
<num>15643</num>
<curr>SAR</curr>
<code/>
</root>
<root>
<order>431as</order>
<type>se134</type>
<num>15643</num>
<curr>USD</curr>
<code/>
</root>
<root>
<order>531as</order>
<type>Tse134</type>
<num>15643</num>
<curr>AED</curr>
<code>
<root>
<amount>10.0</amount>
<auth>Mr.121</auth>
<city>Abudabhi</city>
<desc>testdesc</desc>
<shop>testa</shop>
<store>
<element>
<amount>10.0</amount>
<quantity>71</quantity>
</element>
<element>
<amount>95.33</amount>
<quantity>100</quantity>
</element>
<element>
<amount>-8.0</amount>
<quantity>300</quantity>
</element>
</store>
</root>
</code>
</root>
尝试使用我在其中一个博客中找到的以下 XSLT。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx" xmlns:exsl="http://exslt.org/common" xmlns:so="http://stackoverflow.com/questions/13007280" exclude-result-prefixes="xsl xs json so exsl">
<xsl:output indent="yes" encoding="UTF-8"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="quot" select="'"'"/>
<xsl:variable name="numbers" select="'0123456789'"/>
<xsl:variable name="booleans" select="'tf'"/>
<xsl:template match="/*">
<xsl:variable name="t1">
<xsl:call-template name="object">
<xsl:with-param name="json-in" select="."/>
</xsl:call-template>
</xsl:variable>
<xsl:apply-templates select="exsl:node-set($t1)/so:output/*" mode="copy-sans-namespace"/>
</xsl:template>
<xsl:template match="*" mode="copy-sans-namespace">
<xsl:element name="{name()}" namespace="{namespace-uri()}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates mode="copy-sans-namespace"/>
</xsl:element>
</xsl:template>
<xsl:template name="field">
<!-- Input like: "Open": "25.15" bla -->
<!-- output like: <so:output><Open>25.15</Open></so:output> <so:extra>bla</so:extra> -->
<xsl:param name="json-in"/>
<xsl:variable name="field-name" select="substring-before(substring-after($json-in,$quot),$quot)"/>
<xsl:variable name="remainder" select="substring-after($json-in,':')"/>
<xsl:call-template name="value">
<xsl:with-param name="json-in" select="$remainder"/>
<xsl:with-param name="parent-ele" select="$field-name"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="fields">
<!-- Input like: "Open": "25.15" , "High": "25.15" } bla -->
<!-- output like: <so:output><Open>25.15</Open><High>25.15</High></so:output> <so:extra>} bla</so:extra> -->
<xsl:param name="json-in"/>
<xsl:variable name="n" select="normalize-space($json-in)"/>
<xsl:choose>
<xsl:when test="substring($n,1,1) = $quot">
<xsl:variable name="t1">
<xsl:call-template name="field">
<xsl:with-param name="json-in" select="$n"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="t2" select="normalize-space( exsl:node-set($t1)/so:extra) "/>
<xsl:variable name="t3">
<xsl:choose>
<xsl:when test="substring($t2,1,1)=','">
<xsl:call-template name="fields">
<xsl:with-param name="json-in" select="substring-after($t2,',')"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$t2">
<so:extra>
<xsl:value-of select="$t2"/>
</so:extra>
</xsl:when>
</xsl:choose>
</xsl:variable>
<so:output>
<xsl:copy-of select="exsl:node-set($t1)/so:output/* | exsl:node-set($t3)/so:output/*"/>
</so:output>
<xsl:copy-of select="exsl:node-set($t3)/so:extra"/>
</xsl:when>
<xsl:when test="$n">
<so:extra>
<xsl:value-of select="$n"/>
</so:extra>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template name="object">
<!-- Input like: { X } bla -->
<!-- output like: <so:output>fields(X)</so:output> <so:extra>bla</so:extra> -->
<xsl:param name="json-in"/>
<xsl:param name="parent-ele" select="''"/>
<xsl:variable name="t1" select="normalize-space(substring-after($json-in,'{'))"/>
<xsl:variable name="t2">
<xsl:call-template name="fields">
<xsl:with-param name="json-in" select="$t1"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="t3" select="normalize-space(substring-after( exsl:node-set($t2)/so:extra, '}'))"/>
<so:output>
<xsl:choose>
<xsl:when test="$parent-ele">
<xsl:element name="{$parent-ele}">
<xsl:copy-of select="exsl:node-set($t2)/so:output/node()"/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="exsl:node-set($t2)/so:output/node()"/>
</xsl:otherwise>
</xsl:choose>
</so:output>
<xsl:if test="$t3">
<so:extra>
<xsl:value-of select="$t3"/>
</so:extra>
</xsl:if>
</xsl:template>
<xsl:template name="objects">
<xsl:param name="json-in"/>
<xsl:param name="parent-ele"/>
<xsl:variable name="n" select="normalize-space($json-in)"/>
<xsl:choose>
<xsl:when test="substring($n,1,1) = '{'">
<xsl:variable name="t1">
<xsl:call-template name="object">
<xsl:with-param name="json-in" select="$n"/>
<xsl:with-param name="parent-ele" select="$parent-ele"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="t2" select="normalize-space( exsl:node-set($t1)/so:extra) "/>
<xsl:variable name="t3">
<xsl:choose>
<xsl:when test="substring($t2,1,1)='{'">
<xsl:call-template name="objects">
<xsl:with-param name="json-in" select="$t2"/>
<xsl:with-param name="parent-ele" select="$parent-ele"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="substring($t2,1,1)=',' and substring(normalize-space(substring-after($t2,',')),1,1)='{'">
<xsl:call-template name="objects">
<xsl:with-param name="json-in" select="normalize-space(substring-after($t2,','))"/>
<xsl:with-param name="parent-ele" select="$parent-ele"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$t2">
<so:extra>
<xsl:value-of select="$t2"/>
</so:extra>
</xsl:when>
</xsl:choose>
</xsl:variable>
<so:output>
<xsl:copy-of select="exsl:node-set($t1)/so:output/* | exsl:node-set($t3)/so:output/*"/>
</so:output>
<xsl:copy-of select="exsl:node-set($t3)/so:extra"/>
</xsl:when>
<xsl:when test="$n">
<so:extra>
<xsl:value-of select="$n"/>
</so:extra>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template name="array">
<!-- Input like: [ X1 X2 ] bla -->
<!-- output like: <so:output><Y>X1</Y><Y>X2</Y></so:output> <so:extra>}bla</so:extra> -->
<xsl:param name="json-in"/>
<xsl:param name="parent-ele"/>
<xsl:variable name="t1" select="normalize-space(substring-after($json-in,'['))"/>
<xsl:variable name="t2">
<xsl:call-template name="objects">
<xsl:with-param name="json-in" select="$t1"/>
<xsl:with-param name="parent-ele" select="$parent-ele"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="t3">
<xsl:choose>
<xsl:when test="contains(substring-before(exsl:node-set($t2)/so:extra,']'),',')">
<xsl:value-of select="normalize-space(substring-after(exsl:node-set($t2)/so:extra,','))"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="normalize-space(substring-after(exsl:node-set($t2)/so:extra,']'))"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="t4">
<xsl:element name="{$parent-ele}">
<xsl:for-each select="$t2/so:output/*[local-name(.)=$parent-ele]">
<xsl:variable name="self" select="."/>
<xsl:variable name="tempResult">
<xsl:element name="{concat($parent-ele,'_element')}">
<xsl:copy-of select="exsl:node-set($self/*)"/>
</xsl:element>
</xsl:variable>
<xsl:copy-of select="exsl:node-set($tempResult)"/>
</xsl:for-each>
</xsl:element>
</xsl:variable>
<xsl:variable name="t5" select="exsl:node-set($t4)"/>
<so:output>
<xsl:copy-of select="$t5"/>
</so:output>
<xsl:if test="$t3">
<so:extra>
<xsl:value-of select="$t3"/>
</so:extra>
</xsl:if>
</xsl:template>
<xsl:template name="value">
<!-- Input like either array, object or string -->
<!-- output like either array, object or string -->
<xsl:param name="json-in"/>
<xsl:param name="parent-ele"/>
<xsl:variable name="first-letter" select="substring(normalize-space($json-in),1,1)"/>
<xsl:choose>
<xsl:when test="$first-letter='{'">
<xsl:call-template name="object">
<xsl:with-param name="json-in" select="$json-in"/>
<xsl:with-param name="parent-ele" select="$parent-ele"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$first-letter='['">
<xsl:call-template name="array">
<xsl:with-param name="json-in" select="$json-in"/>
<xsl:with-param name="parent-ele" select="$parent-ele"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$first-letter=$quot">
<xsl:call-template name="string">
<xsl:with-param name="json-in" select="$json-in"/>
<xsl:with-param name="parent-ele" select="$parent-ele"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="contains($numbers,$first-letter)">
<xsl:call-template name="number">
<xsl:with-param name="json-in" select="$json-in"/>
<xsl:with-param name="parent-ele" select="$parent-ele"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="contains($booleans,$first-letter)">
<xsl:call-template name="boolean">
<xsl:with-param name="json-in" select="$json-in"/>
<xsl:with-param name="parent-ele" select="$parent-ele"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<so:output>ERROR</so:output>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="string">
<!-- Input like: "X" bla -->
<!-- output like: <so:output><Y>X</Y></so:output> <so:extra>bla</so:extra> -->
<xsl:param name="json-in"/>
<xsl:param name="parent-ele"/>
<xsl:variable name="value" select="substring-before(substring-after($json-in,$quot),$quot)"/>
<xsl:variable name="remainder" select="normalize-space(substring-after(substring-after($json-in,$quot),$quot))"/>
<so:output>
<xsl:element name="{$parent-ele}">
<xsl:value-of select="$value"/>
</xsl:element>
</so:output>
<xsl:if test="$remainder">
<so:extra>
<xsl:value-of select="$remainder"/>
</so:extra>
</xsl:if>
</xsl:template>
<xsl:template name="number">
<!-- Input like: "X" bla -->
<!-- output like: <so:output><Y>X</Y></so:output> <so:extra>bla</so:extra> -->
<xsl:param name="json-in"/>
<xsl:param name="parent-ele"/>
<xsl:variable name="value">
<xsl:choose>
<xsl:when test="contains(substring-before($json-in,','),'}')">
<xsl:value-of select="normalize-space(substring-before($json-in,'}'))"/>
</xsl:when>
<xsl:when test="contains(substring-before($json-in,','),']')">
<xsl:value-of select="normalize-space(substring-before($json-in,']'))"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="normalize-space(substring-before($json-in,','))"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="remainder">
<xsl:choose>
<xsl:when test="contains(substring-before($json-in,','),'}')">
<xsl:value-of select="concat('}',normalize-space(substring-after($json-in,'}')))"/>
</xsl:when>
<xsl:when test="contains(substring-before($json-in,','),']')">
<xsl:value-of select="concat(']',normalize-space(substring-after($json-in,']')))"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat(',',normalize-space(substring-after($json-in,',')))"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<so:output>
<xsl:element name="{$parent-ele}">
<xsl:value-of select="$value"/>
</xsl:element>
</so:output>
<xsl:if test="$remainder">
<so:extra>
<xsl:value-of select="$remainder"/>
</so:extra>
</xsl:if>
</xsl:template>
<xsl:template name="boolean">
<!-- Input like: "X" bla -->
<!-- output like: <so:output><Y>X</Y></so:output> <so:extra>bla</so:extra> -->
<xsl:param name="json-in"/>
<xsl:param name="parent-ele"/>
<xsl:variable name="value">
<xsl:choose>
<xsl:when test="contains(substring-before($json-in,','),'}')">
<xsl:value-of select="normalize-space(substring-before($json-in,'}'))"/>
</xsl:when>
<xsl:when test="contains(substring-before($json-in,','),']')">
<xsl:value-of select="normalize-space(substring-before($json-in,']'))"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="normalize-space(substring-before($json-in,','))"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="remainder">
<xsl:choose>
<xsl:when test="contains(substring-before($json-in,','),'}')">
<xsl:value-of select="concat('}',normalize-space(substring-after($json-in,'}')))"/>
</xsl:when>
<xsl:when test="contains(substring-before($json-in,','),']')">
<xsl:value-of select="concat(']',normalize-space(substring-after($json-in,']')))"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat(',',normalize-space(substring-after($json-in,',')))"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<so:output>
<xsl:element name="{$parent-ele}">
<xsl:value-of select="$value"/>
</xsl:element>
</so:output>
<xsl:if test="$remainder">
<so:extra>
<xsl:value-of select="$remainder"/>
</so:extra>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
答:
1赞
michael.hor257k
8/31/2023
#1
这里有一个你可以用它作为起点的东西(实际上,它几乎已经完成,你只需要填写一些空白)。这遵循我在对您的问题的评论中所说的:它是专门针对您的 JSON 结构量身定制的。
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="code">
<xsl:copy>
<!-- extract values from elements at the top level -->
<desc>
<xsl:value-of select="substring-before(substring-after(., '"desc":"'), '"')" />
</desc>
<city>
<xsl:value-of select="substring-before(substring-after(., '"city":"'), '"')" />
</city>
<!-- ... continue for other elements at the top level -->
<!-- process the array -->
<store>
<xsl:call-template name="process-array">
<xsl:with-param name="array" select="substring-before(substring-after(., '['), ']')" />
</xsl:call-template>
</store>
</xsl:copy>
</xsl:template>
<xsl:template name="process-array">
<xsl:param name="array"/>
<xsl:param name="delimiter" select="'},{'"/>
<xsl:variable name="object" select="substring-before(concat($array, ',{'), $delimiter)" />
<xsl:if test="$object">
<element>
<quantity>
<xsl:value-of select="substring-before(substring-after($object, '"quantity":'), ',')" />
</quantity>
<amount>
<xsl:value-of select="substring-after($object, '"amount":')" />
</amount>
</element>
</xsl:if>
<xsl:if test="contains($array, $delimiter)">
<!-- recursive call -->
<xsl:call-template name="process-array">
<xsl:with-param name="array" select="substring-after($array, $delimiter)"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
应用于输入示例后,将返回:
结果
<?xml version="1.0" encoding="UTF-8"?>
<root>
<root>
<order>131as</order>
<type>se134</type>
<num>15643</num>
<curr>USD</curr>
<code>
<desc>Testing123</desc>
<city>Dubai</city>
<store>
<element>
<quantity>1</quantity>
<amount>2.00</amount>
</element>
<element>
<quantity>100</quantity>
<amount>-8.33</amount>
</element>
<element>
<quantity>300</quantity>
<amount>-15.00</amount>
</element>
</store>
</code>
</root>
<root>
<order>231as</order>
<type>se134</type>
<num>15643</num>
<curr>AED</curr>
<code>
<desc>testdesc</desc>
<city>SHarjah</city>
<store>
<element>
<quantity>1</quantity>
<amount>10.00</amount>
</element>
<element>
<quantity>100</quantity>
<amount>98.33</amount>
</element>
<element>
<quantity>300</quantity>
<amount>-1.00</amount>
</element>
</store>
</code>
</root>
<root>
<order>331as</order>
<type>se134</type>
<num>15643</num>
<curr>SAR</curr>
<code>
<desc/>
<city/>
<store/>
</code>
</root>
<root>
<order>431as</order>
<type>se134</type>
<num>15643</num>
<curr>USD</curr>
<code>
<desc/>
<city/>
<store/>
</code>
</root>
<root>
<order>531as</order>
<type>Tse134</type>
<num>15643</num>
<curr>AED</curr>
<code>
<desc>testdesc</desc>
<city>Abudabhi</city>
<store>
<element>
<quantity>71</quantity>
<amount>10.00</amount>
</element>
<element>
<quantity>100</quantity>
<amount>95.33</amount>
</element>
<element>
<quantity>300</quantity>
<amount>-8.00</amount>
</element>
</store>
</code>
</root>
</root>
2赞
Michael Kay
8/31/2023
#2
在纯 XSLT 1.0 中为 JSON 编写正确且完整的解析器是一项具有挑战性的任务,但可以完成。
事实上,它已经做到了:https://bottlecaps.de/rex/ 的 Gunther Rademacher 的 Rex 解析器生成器将为任何语法生成一个 XSLT 解析器,而 JSON 是“开箱即用”的语法之一。
Rex 是一款出色的软件,可悲的是,它遭受了令人震惊的文档(并且不是真正的开源,尽管它可以免费使用)。
评论
0赞
Martin Honnen
8/31/2023
但是 Rex 是否支持 XSLT 1.0?
0赞
Michael Kay
9/1/2023
问得好。我的记忆是它确实如此,但我可能弄错了,没有任何文档......
1赞
Martin Honnen
8/31/2023
#3
在许多平台上都可以使用 XSLT 3(例如使用 Saxon HE Java、Saxon HE .NET、SaxonC HE、SaxonJS),而在 XSLT 3 中,您可以使用例如 和自定义模板来实现结果:json-to-xml
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
exclude-result-prefixes="#all"
expand-text="yes"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="code[parse-json(.) instance of map(*)]">
<xsl:copy>
<xsl:apply-templates select="json-to-xml(.)!* => sort((), function($el) { $el/@key})" mode="json"/>
</xsl:copy>
</xsl:template>
<xsl:mode name="json" on-no-match="shallow-copy"/>
<xsl:template mode="json" match="fn:*[@key]">
<xsl:element name="{@key}">
<xsl:apply-templates mode="#current"/>
</xsl:element>
</xsl:template>
<xsl:template mode="json" match="fn:array[@key]/fn:map[not(@key)]">
<element>
<xsl:apply-templates select="* => sort((), function($el) { $el/@key })" mode="#current"/>
</element>
</xsl:template>
<xsl:template mode="json" match="/fn:map[not(@key)]">
<root>
<xsl:apply-templates select="* => sort((), function($el) { $el/@key })" mode="#current"/>
</root>
</xsl:template>
</xsl:stylesheet>
运行该示例的 .NET 7 控制台代码示例如下:
using net.liberty_development.SaxonHE11s9apiExtensions;
using net.sf.saxon.s9api;
var xml = """
<root>
<root>
<order>131as</order>
<type>se134</type>
<num>15643</num>
<curr>USD</curr>
<code>{"desc":"Testing123","city":"Dubai","auth":"author","store":[{"quantity":1,"amount":2.00},{"quantity":100,"amount":-8.33},{"quantity":300,"amount":-15.00}]}</code>
</root>
<root>
<order>231as</order>
<type>se134</type>
<num>15643</num>
<curr>AED</curr>
<code>{"desc":"testdesc","city":"SHarjah","auth":"Mohammad","amount":20.00,"shop":"test","store":[{"quantity":1,"amount":10.00},{"quantity":100,"amount":98.33},{"quantity":300,"amount":-1.00}]}</code>
</root>
<root>
<order>331as</order>
<type>se134</type>
<num>15643</num>
<curr>SAR</curr>
<code/>
</root>
<root>
<order>431as</order>
<type>se134</type>
<num>15643</num>
<curr>USD</curr>
<code/>
</root>
<root>
<order>531as</order>
<type>Tse134</type>
<num>15643</num>
<curr>AED</curr>
<code>{"desc":"testdesc","city":"Abudabhi","auth":"Mr.121","amount":10.00,"shop":"testa","store":[{"quantity":71,"amount":10.00},{"quantity":100,"amount":95.33},{"quantity":300,"amount":-8.00}]}</code>
</root>
</root>
""";
var xslt = """
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
exclude-result-prefixes="#all"
expand-text="yes"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="code[parse-json(.) instance of map(*)]">
<xsl:copy>
<xsl:apply-templates select="json-to-xml(.)!* => sort((), function($el) { $el/@key})" mode="json"/>
</xsl:copy>
</xsl:template>
<xsl:mode name="json" on-no-match="shallow-copy"/>
<xsl:template mode="json" match="fn:*[@key]">
<xsl:element name="{@key}">
<xsl:apply-templates mode="#current"/>
</xsl:element>
</xsl:template>
<xsl:template mode="json" match="fn:array[@key]/fn:map[not(@key)]">
<element>
<xsl:apply-templates select="* => sort((), function($el) { $el/@key })" mode="#current"/>
</element>
</xsl:template>
<xsl:template mode="json" match="/fn:map[not(@key)]">
<root>
<xsl:apply-templates select="* => sort((), function($el) { $el/@key })" mode="#current"/>
</root>
</xsl:template>
</xsl:stylesheet>
""";
var processor = new Processor(false);
var xsltCompiler = processor.newXsltCompiler();
var xsltExecutable = xsltCompiler.compile(xslt.AsSource());
var xslt30Transformer = xsltExecutable.load30();
xslt30Transformer.transform(xml.AsSource(), processor.NewSerializer(Console.Out));
评论
shop
amount
<shop>testa</shop>