0

いくつかの要素のテキストではなく、最初の要素名に基づいてXMLを並べ替える方法を知りたいです。基本的に、同じレベルの要素'd、e、c、a、b'の要素がある場合は、それらを' a、b、c、d、e'のように並べ替えます。また、もう1つの要件は、a / b / c / d /eのグループを「b、c、d」要素内のテキストで並べ替えることです。したがって、b、c、dの1つのセットに「b1、c1、d1」が含まれ、もう1つのセットに「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>

これを取得したい:(next_tagを「a_elementおよびb_element」でソートし、d_elementを「a_element、b_elementおよびcolumn_name」でソート)

<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?

ただし、要素ごとの順序を適用すると(ほとんどの場合誤って)、すべての要素名がスクランブルされます(要素名の順序から外れます)。

この処理では、xsltで複数のパスを使用して最終結果を得るのは問題ありません。両方(要素と名前で並べ替え)を実行する単一のxslファイルを用意する必要はありません。

この演習全体は、「差分」(または比較を超えて)を実行し、XMLの変更を理解できるようにするためのものです。

4

1 に答える 1

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>

ここで重要な点はselect、aの式が、sort並べ替えの対象となるノードをコンテキストノードとして適用されることです。したがって、next_tagテンプレートは最初にその子を要素名で並べ替え、次に2つの要素が同じ名前の場合は並べ替えられます。それぞれの値、a_elementおよび子b_elementcolumn_name存在する場合)をこの順序で。

于 2013-03-18T16:43:21.687 に答える