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>

所以在对父亲/价值进行排序之后,我应该得到正确的祖父序列

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

换句话说,我想根据父亲/值对子树祖父进行排序。休息一切都应该保持不变。我已经尝试过类似下面的东西..但这只是将源 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 回答