在简单的嵌套结构上按属性排序元素

时间:2013-10-23 23:01:38

标签: xslt

我仍然在努力解决很多XSLT问题,但有一个具体的问题。

我有一个简单的嵌套结构,我想按属性(名称)排序。

该文件具有单个根节点,然后是一系列嵌套节点。我需要让root下的所有节点都在它们的级别内排序。层次结构嵌套到未指定的级别。

输入:

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <node name="A">
    <node name="C"/>
    <node name="B"/>
  </node>
  <node name="F"/>
  <node name="E"/>
</root>

需要转变为:

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <node name="A">
    <node name="B"/>
    <node name="C"/>
  </node>
  <node name="E"/>
  <node name="F"/>
</root>

我无法帮助你解决这个问题。

2 个答案:

答案 0 :(得分:0)

假设您希望元素保持在当前所处的级别内,首先,您需要一个模板来匹配任何元素

<xsl:template match="*">

然后您将使用 xsl:copy 复制元素,并使用 xsl:copy-of 复制任何属性

  <xsl:copy>
     <xsl:copy-of select="@*"/>
     ... more code here...
  </xsl:copy>

然后在 xsl:copy 中,您将使用 xsl:apply-templates 来处理子元素,以及 xsl:sort 选择订单

     <xsl:apply-templates select="*">
        <xsl:sort select="@name" />
     </xsl:apply-templates>

完全放弃这个

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output omit-xml-declaration="yes" indent="yes" />
   <xsl:template match="*">
      <xsl:copy>
         <xsl:copy-of select="@*"/>
         <xsl:apply-templates select="*">
            <xsl:sort select="@name" />
         </xsl:apply-templates>
      </xsl:copy>
   </xsl:template>
</xsl:stylesheet>

当应用于输入XML时,输出以下内容

<root>
  <node name="A">
    <node name="B"/>
    <node name="C"/>
  </node>
  <node name="E"/>
  <node name="F"/>
</root>

答案 1 :(得分:0)

这个答案类似于Tim C,但只是使用xsl:sort的身份变换。这样,如果它们存在,您不会丢失注释或处理指令。

XSLT 1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()">
                <xsl:sort select="@name"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>