2013-03-18 120 views
0

我想知道如何根据第一个元素名称对XML进行排序,而不是根据这些元素中的少数元素进行排序。 如果我在同一级别有元素'd,e,c,a,b'元素,我希望他们被命令为'a,b,c,d,e'。 另一个要求是通过'b,c,d'元素中的文本对a/b/c/d/e组进行排序。因此,如果一组b,c,d中包含'b1,c1,d1',另一组包含'b2,c2,d2',应该先出来(按字母顺序排列,我不需要数字订购)。 (以sql语言:order by b,c,d)按名称对XML元素进行排序,并按文字对元素进一步排序

我有XML如。

<top_tag> 
<next_tag> 
    <a_element>valueX</a_element> 
    <b_element>valueZ</b_element> 
    <d_element> 
    <property>on</property> 
    <header>hello</header> 
    <column_name>columnC</column_name> 
    <a_element>valueX</a_element> 
    <b_element>valueZ</b_element> 
    </d_element> 
    <c_element>valueC</c_element> 
    <d_element> 
    <property>off</property> 
    <header>hi</header> 
    <column_name>columnA</column_name> 
    <a_element>valueX</a_element> 
    <b_element>valueZ</b_element> 
    </d_element> 
</next_tag> 
<next_tag> 
    <a_element>valueA</a_element> 
    <b_element>valueB</b_element> 
    <d_element> 
    <property>on</property> 
    <header>hello</header> 
    <column_name>columnAAA</column_name> 
    <a_element>valueA</a_element> 
    <b_element>valueB</b_element> 
    </d_element> 
    <c_element>valueC</c_element> 
    <d_element> 
    <property>off</property> 
    <header>hi</header> 
    <column_name>columnA</column_name> 
    <a_element>valueA</a_element> 
    <b_element>valueB</b_element> 
    </d_element> 
</next_tag> 
</top_tag> 

我希望得到这样的:(排序由 'a_element和b_element' next_tag,并通过分类 'a_element,b_element和列名' d_element)

<top_tag> 
    <next_tag> 
    <a_element>valueA</a_element> 
    <b_element>valueB</b_element> 
    <c_element>valueC</c_element> 
    <d_element> 
     <a_element>valueA</a_element> 
     <b_element>valueB</b_element> 
     <column_name>columnA</column_name> 
     <header>hi</header> 
     <property>off</property> 
    </d_element> 
    <d_element> 
     <a_element>valueA</a_element> 
     <b_element>valueB</b_element> 
     <column_name>columnAAA</column_name> 
     <header>hello</header> 
     <property>on</property> 
    </d_element> 
    </next_tag> 
    <next_tag> 
    <a_element>valueX</a_element> 
    <b_element>valueZ</b_element> 
    <c_element>valueC</c_element> 
    <d_element> 
     <a_element>valueX</a_element> 
     <b_element>valueZ</b_element> 
     <column_name>columnA</column_name> 
     <header>hi</header> 
     <property>off</property> 
    </d_element> 
    <d_element> 
     <a_element>valueX</a_element> 
     <b_element>valueZ</b_element> 
     <column_name>columnC</column_name> 
     <header>hello</header> 
     <property>on</property> 
    </d_element> 
    </next_tag> 
</top_tag> 

我发现如何订购基于字母顺序这里元素: XSLT to sort nodes by name?

但是,如果我再由元素应用顺序(最有可能不正确地),所有的元素名称变得混乱(出元素名称顺序)。

对于这个处理是蛮好用的多遍用XSLT去最后的结果,我没有要求有一个单独的XSL文件(通过元素和名称排序)同时做两

这整个练习只是让我可以做一个'差异'(或无法比拟),并能够理解XML的变化。

回答

1

可以具有多于一个的<xsl:sort>内的apply-templatesfor-each

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

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

    <xsl:template match="top_tag"> 
    <top_tag> 
     <xsl:apply-templates select="next_tag"> 
     <xsl:sort select="a_element" /> 
     <xsl:sort select="b_element" /> 
     </xsl:apply-templates> 
    </top_tag> 
    </xsl:template> 

    <xsl:template match="next_tag"> 
    <next_tag> 
     <xsl:apply-templates select="*"> 
     <xsl:sort select="name()" /> 
     <xsl:sort select="a_element" /> 
     <xsl:sort select="b_element" /> 
     <xsl:sort select="column_name" /> 
     </xsl:apply-templates> 
    </next_tag> 
    </xsl:template> 

    <xsl:template match="d_element"> 
    <d_element> 
     <xsl:apply-templates select="*"> 
     <xsl:sort select="name()" /> 
     </xsl:apply-templates> 
    </d_element> 
    </xsl:template> 
</xsl:stylesheet> 

这里的关键点是,一个sortselect表达式应用于与节点被考虑排序作为上下文节点,从而该next_tag模板将其子最早由元素名称进行排序,然后如果两个元素有相同的名字,他们将通过各自的a_elementb_elementcolumn_name孩子的值(如果有的话)进行排序,按照这个顺序。

相关问题