我想用XSL转换对一个XML文件进行排序.
<root>
<element>
<name>A</name>
</element>
<element>
<name>B</name>
</element>
<element>
<name>C</name>
</element>
</root>
Run Code Online (Sandbox Code Playgroud)
必须按以下名称列表进行排序:C,A,B,以便生成的XML为:
<root>
<element>
<name>C</name>
</element>
<element>
<name>A</name>
</element>
<element>
<name>B</name>
</element>
</root>
Run Code Online (Sandbox Code Playgroud)
显然,要排序的值列表应该是非常动态的(XSLT的参数,另一个XML文件......).知道如何在XSLT中做到这一点?
谢谢,克里斯托夫
这种转变:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pSortingValues" select="'C,A,B'"/>
<xsl:variable name="vSortingValues" select=
"concat(',', $pSortingValues, ',')"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="*">
<xsl:sort data-type="number" select=
"string-length(substring-before($vSortingValues,concat(',',name,',')))"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
当应用于提供的XML文档时:
<root>
<element>
<name>A</name>
</element>
<element>
<name>B</name>
</element>
<element>
<name>C</name>
</element>
</root>
Run Code Online (Sandbox Code Playgroud)
产生想要的,正确的结果:
<root>
<element>
<name>C</name>
</element>
<element>
<name>A</name>
</element>
<element>
<name>B</name>
</element>
</root>
Run Code Online (Sandbox Code Playgroud)
请注意:
所需的排序值列表是pSortingValues全局参数,可以在转换外部提供.
身份规则用于"按原样"复制所有节点.
顶部元素的身份规则被覆盖.顶部元素被部分复制,其属性被复制,然后模板被应用于具有<xsl:sort>子指令的所有子元素,该子指令指定要使用的确切排序键 - 如何在pSortingValues值的前面使用element子名称.
更新:如@Alejandro所述,这:
<xsl:sort data-type="number" select=
"string-length(substring-before($vSortingValues,concat(',',name,',')))"/>
Run Code Online (Sandbox Code Playgroud)
可以简化为:
<xsl:sort data-type="number" select=
"substring-before($vSortingValues,concat(',',name,','))"/>
Run Code Online (Sandbox Code Playgroud)