1

私は、xmlドキュメントの一部(完全なツリーではない)をソートする必要があるという要件に取り組んできました。

<Root>
<AllData>
    <Data_not_to_be_sorted>
        <Additional_data1>
            <Some_test_data1/>
            <Some_test_data2/>
        </Additional_data1>
    </Data_not_to_be_sorted>
    <RealData>
        <Some_data1/>
        <Some_data2/>
        <GrandFather>
            <Data_required_as_it_is></Data_required_as_it_is>
            <Father>
                <Value>4</Value>
                <Name>name in 4</Name>
            </Father>
        </GrandFather>
        <GrandFather>
        <Data_required_as_it_is></Data_required_as_it_is>
            <Father>
                <Value>3</Value>
                <Name>name in 3</Name>
            </Father>
        </GrandFather>
    </RealData>
            <RealData>
        <Some_data1/>
        <Some_data2/>
        <GrandFather>
            <Data_required_as_it_is></Data_required_as_it_is>
            <Father>
                <Value>2</Value>
                <Name>name in 2</Name>
            </Father>
        </GrandFather>
        <GrandFather>
        <Data_required_as_it_is></Data_required_as_it_is>
            <Father>
                <Value>1</Value>
                <Name>name in 1</Name>
            </Father>
        </GrandFather>
    </RealData>

</AllData>
</Root>

したがって、Father / Valueで並べ替えた後、GrandFatherの正しいシーケンスを取得する必要があります

<Root>
<AllData>
    <Data_not_to_be_sorted>
        <Additional_data1>
            <Some_test_data1/>
            <Some_test_data2/>
        </Additional_data1>
    </Data_not_to_be_sorted>
    <RealData>
        <Some_data1/>
        <Some_data2/>
        <GrandFather>
            <Data_required_as_it_is></Data_required_as_it_is>
            <Father>
                <Value>3</Value>
                <Name>name in 3</Name>
            </Father>
        </GrandFather>
        <GrandFather>
        <Data_required_as_it_is></Data_required_as_it_is>
            <Father>
                <Value>4</Value>
                <Name>name in 4</Name>
            </Father>
        </GrandFather>
    </RealData>
            <RealData>
        <Some_data1/>
        <Some_data2/>
        <GrandFather>
            <Data_required_as_it_is></Data_required_as_it_is>
            <Father>
                <Value>1</Value>
                <Name>name in 1</Name>
            </Father>
        </GrandFather>
        <GrandFather>
        <Data_required_as_it_is></Data_required_as_it_is>
            <Father>
                <Value>2</Value>
                <Name>name in 2</Name>
            </Father>
        </GrandFather>
    </RealData>

</AllData>
</Root>

つまり、Father/Valueに基づいてサブツリーGrandFatherを並べ替えたいと思います。残りはすべて同じままにする必要があります。以下のようなものを試しましたが、これはソースxmlを出力にコピーするだけです。

<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- Template to copy the nodes as they are -->

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


<xsl:template match="GrandFather">
<xsl:copy>
    <xsl:apply-templates select="@*"/>
    <xsl:apply-templates select="node()">    
    <xsl:sort select="self::Father/Value" data-type="number"/>
    </xsl:apply-templates>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>
4

2 に答える 2

2

この正しい、より短く、より単純でより一般的な変換

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

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

 <xsl:template match="*[F]">
  <xsl:copy>
   <xsl:apply-templates select="@*"/>

   <xsl:apply-templates select="node()">
    <xsl:sort select="self::F/Value" data-type="number"/>
   </xsl:apply-templates>
  </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

提供されたXMLドキュメントに適用した場合:

<Root>
    <AllData>
        <Data_not_to_be_sorted>
            <Additional_data1>
                <Some_test_data1/>
                <Some_test_data2/>
            </Additional_data1>
        </Data_not_to_be_sorted>
        <data>
            <Some_data1></Some_data1>
            <Some_data2></Some_data2>
            <F>
                <Value>2</Value>
                <Name>name in 2</Name>
            </F>
            <F>
                <Value>1</Value>
                <Name>name in 1</Name>
            </F>
        </data>
        <data>
            <Some_data1></Some_data1>
            <Some_data2></Some_data2>
            <F>
                <Value>4</Value>
                <Name>name 4</Name>
            </F>
            <F>
                <Value>3</Value>
                <Name>name in 3</Name>
            </F>
        </data>
    </AllData>
</Root>

必要な正しい結果を生成します。

<Root>
   <AllData>
      <Data_not_to_be_sorted>
         <Additional_data1>
            <Some_test_data1/>
            <Some_test_data2/>
         </Additional_data1>
      </Data_not_to_be_sorted>
      <data>
         <Some_data1/>
         <Some_data2/>
         <F>
            <Value>1</Value>
            <Name>name in 1</Name>
         </F>
         <F>
            <Value>2</Value>
            <Name>name in 2</Name>
         </F>
      </data>
      <data>
         <Some_data1/>
         <Some_data2/>
         <F>
            <Value>3</Value>
            <Name>name in 3</Name>
         </F>
         <F>
            <Value>4</Value>
            <Name>name 4</Name>
         </F>
      </data>
   </AllData>
</Root>
于 2012-05-05T04:49:52.963 に答える
0

問題はF/Value、の子ではないということですRoot。また、Root(使用可能な並べ替えキーを指定した場合)すぐ下に並べ替えを適用すると、ルートの子要素のみが並べ替えられます。このようなことをする必要があります(テストされていません):

<xsl:template match="@* | node()">
    <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
</xsl:template>
<xsl:template match="data">
    <xsl:apply-templates select="Some_data1"/>
    <xsl:apply-templates select="Some_data2"/>
    <xsl:apply-templates select="F">
        <xsl:sort select="Value"/>
    </xsl:apply-templates>
</xsl:template>

重要なのは、スタイルシートが手続き型ではなく宣言型であることを覚えておくことです。XSLTエンジンはXMLを読み取り、各入力要素でスタイルシートを調べて何を出力するかを決定します。

于 2012-05-04T18:45:32.443 に答える