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',那么带有 '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>

我在这里找到了如何根据字母顺序对元素进行排序: XSL​​T to sort nodes by name?

但是,如果我随后按元素应用顺序(很可能是错误的),所有元素名称都会被打乱(超出元素名称顺序)。

对于此处理,可以使用 xslt 的多次传递来获得最终结果,我不需要一个 xsl 文件同时进行(按元素和名称排序)

整个练习只是为了让我可以做一个“差异”(或超越比较)并能够理解 XML 中的变化。

4

1 回答 1

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>

这里的关键点是,selecta的表达式sort应用了考虑排序的节点作为上下文节点,因此next_tag模板将首先按元素名称对其子节点进行排序,然后如果两个元素具有相同的名称,则将它们排序为他们各自的价值a_elementb_elementcolumn_name孩子(如果有的话),按顺序。

于 2013-03-18T16:43:21.687 回答