【问题标题】:Sort XML elements by name, and further sort elements by text按名称对 XML 元素进行排序,然后按文本对元素进行进一步排序
【发布时间】:2013-03-18 16:31:31
【问题描述】:

我想知道如何根据第一个元素名称而不是其中几个元素的文本对 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 中的变化。

【问题讨论】:

    标签: xslt


    【解决方案1】:

    apply-templatesfor-each 中可以有多个 &lt;xsl:sort&gt;

    <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 子元素(如果有)的值按顺序排序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-31
      • 2021-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多