使用XSLT重新排序xml元素

Ber*_*Cim 1 xslt

我有以下xml片段出现在很多地方,但TYPE元素出现的顺序是随机的.此外,没有保证所有类型都可用,例如某些代码段可能包含Visio和/或Outlook或任何其他节点丢失:

<Applications>
    <Type Name="Word">
    <Type Name="Excel">
    <Type Name="PowerPoint">
    <Type Name="Visio">
    <Type Name="Outlook">
</Applications>
Run Code Online (Sandbox Code Playgroud)

我想重新排序Type元素,以便Type Excel存在,它将始终位于列表的顶部,依此类推:

if EXCEL exists, 
place TYPE Excel at the top.
if WORD exists,
place TYPE Word next,
.
.
.
Run Code Online (Sandbox Code Playgroud)

我尝试过xsl:copy,几个xsl:if然后应用特定的模板,xsl:whens.不幸的是,这些都不适合我.我看了另一篇关于重新排序xml节点元素的帖子,这看起来不像我想要的(它使用了xsl:call-templates,我没有).

我有一些开头的东西,如下所示,我想我需要将上面的操作代码添加到底部:

XML已更新

<xsl:template match="Applications">
    <xsl:element name="Applications">
        <xsl:element name="Type">
            <xsl:attribute name="Name">PowerPoint</xsl:attribute>
        </xsl:element>
        <xsl:element name="Type">
            <xsl:attribute name="Name">Outlook</xsl:attribute>
        </xsl:element>
        <xsl:apply-templates>
            <xsl:sort select="string-length(substring-before(';Excel;PowerPoint;Outlook;Word;Visio',@Name))"/>
        </xsl:apply-templates>
    </xsl:element>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)

通缉:

<Applications>
    <Type Name="Excel">
    <Type Name="PowerPoint">
    <Type Name="Outlook">
    <Type Name="Word">
    <Type Name="Visio">
</Applications>
Run Code Online (Sandbox Code Playgroud)

但得到了:

<Applications>
    <Type Name="PowerPoint">
    <Type Name="Outlook">
    <Type Name="Excel">
    <Type Name="Word">
    <Type Name="Visio">
</Applications>
Run Code Online (Sandbox Code Playgroud)

感谢帮助让这件事工作...... TIA.

Fly*_*179 7

看看进入<xsl:sort>指令,这是作为的一个孩子<xsl:apply-templates><xsl:for-each>指令.

如果你想要按照自然顺序排序的东西(例如数字或字母顺序),那么它就相当简单,只需指定一下即可<xsl:sort select="@Name">.

如果你想要一个自定义排序顺序,有很多选项,但如果你的列表不是很大,那么试试这个:

<xsl:sort select="number-format(string-length(substring-before(
   ';Excel;Word;PowerPoint;Outlook;Visio'
   ,@Name)),'000')" />
Run Code Online (Sandbox Code Playgroud)

这基本上取了你要查找的字符串之前的字符串部分,并对其长度进行排序,强制三位数来处理词法排序.Excel解析为001,Word解析为007等

或者,您可以像这样强制它:

<xsl:template match="Application">
  <xsl:copy>
    <xsl:apply-templates select="Type[@Name='Excel']" />
    <xsl:apply-templates select="Type[@name='Word']" />
    <!-- etc.. -->
  </xsl:copy>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)

任何不存在的东西都会被简单地跳过,因为没有什么可以应用模板.它更简单,但更冗长.