XSLT对xml文档的一部分进行排序

XSLT对xml文档的一部分进行排序,xslt,Xslt,我一直在研究一个需要对xml文档的一部分(而不是完整的树)进行排序的需求 4. 名字在4 3. 名字在3 2. 名字在2 1. 名字在1 所以在对父/值排序之后,我应该得到正确的祖父顺序 <Root> <AllData> <Data_not_to_be_sorted> <Additional_data1> <Some_test_data1/> <Some_

我一直在研究一个需要对xml文档的一部分(而不是完整的树)进行排序的需求


4.
名字在4
3.
名字在3
2.
名字在2
1.
名字在1
所以在对父/值排序之后,我应该得到正确的祖父顺序

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

3.
名字在3
4.
名字在4
1.
名字在1
2.
名字在2
换句话说,我想根据父/值对子树祖父进行排序。其余的一切都应该保持不变。我尝试了下面的方法……但这只是将源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>

问题在于
F/Value
不是
根的子级。此外,在
根目录下应用排序(如果您提供了可用的排序键)将只对根目录的子元素进行排序。您将需要执行以下操作(未经测试):



关键是要记住样式表是声明性的,而不是过程性的。XSLT引擎读取您的XML,并在每个输入元素上查看样式表以决定输出什么。

问题在于
F/Value
不是
Root
的子元素。此外,在
根目录下应用排序(如果您提供了可用的排序键)将只对根目录的子元素进行排序。您将需要执行以下操作(未经测试):

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


关键是要记住样式表是声明性的,而不是过程性的。XSLT引擎读取您的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>
<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>

2.
名字在2
1.
名字在1
4.
名字4
3.
名字在3
生成所需的正确结果:

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

1.
名字在1
2.
名字在2
3.
名字在3
4.
名字4

此正确、更短、更简单且更通用的转换

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

2.
名字在2
1.
名字在1
4.
名字4
3.
名字在3
生成所需的正确结果:

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

1.
名字在1
2.
名字在2
3.
名字在3
4.
名字4

一般来说,当你说某些东西“不工作”时,你需要指定如何:不编译?在运行时崩溃?意外的结果?实际上,不工作意味着,这段代码按原样给了我输出…所以我得到了与源代码相同的输出。一般来说,当你说某些东西“不工作”时,你需要指定如何:不会编译?在运行时崩溃?意外的结果?事实上,不工作意味着,这段代码将按原样给我输出…因此我得到与源代码相同的输出。非常感谢,您的回答帮助我编写了正确的代码…这是适用于此要求的代码。。。我需要做的唯一一件事就是在代码中添加和标记以使代码正常工作…非常感谢:)非常感谢,您的回答帮助我编写了正确的代码…以下是为满足此要求而工作的代码。。。我需要做的唯一一件事就是在代码中添加和标记以使代码正常工作…非常感谢:)嗨Dimitre,谢谢你的解决方案:)…但是我的要求有点改变..现在我需要根据孙子值对祖父排序..我是