基于值列表在XSLT中对XML进行排序

Chr*_*phe 5 xml sorting xslt

我想用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中做到这一点?

谢谢,克里斯托夫

Dim*_*hev 9

这种转变:

<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)

请注意:

  1. 所需的排序值列表是pSortingValues全局参数,可以在转换外部提供.

  2. 身份规则用于"按原样"复制所有节点.

  3. 顶部元素的身份规则被覆盖.顶部元素被部分复制,其属性被复制,然后模板被应用于具有<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)