我想知道如何根据第一个元素名称对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',那么首先应该出现'(1)的设置(按字母顺序排列,我不需要数字订购)。 (用sql术语:按b,c,d排序)
我有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和column_name'排序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的变化。
答案 0 :(得分:1)
您可以在<xsl:sort>
或apply-templates
for-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>
这里的关键点是select
的{{1}}表达式应用于被视为排序的节点作为上下文节点,因此sort
模板将首先对其子项进行排序按元素名称,然后如果两个元素具有相同的名称,它们将按其各自的next_tag
,a_element
和b_element
子元素(如果有)的值按顺序排序。