按多个元素排序

时间:2012-10-31 23:24:36

标签: xml xslt xslt-1.0

我熟悉XSLT的基础知识,但我遇到了一个奇怪的情况,我似乎无法弄清楚。我为此感到抱歉这么久,但我真的很感激你能提供的任何帮助。

我想根据已排序的品牌/值/ @名称和文档/值/ @名称的串联对Level_5节点进行排序,以便排序Level_5

XML unsorted:
<Root att="x">
  <Level_1 Name="NEW Level">    
    <Level_2>      
      <Level_3 Name="nameLvl_3">        
        <Level_4>       
          <Level_5 Name="aa">
            <Brand>
              <Value Name="Text" Value="1" />
            </Brand>            
        <Docs>
              <Value Name="Pro" Value="2" />
              <Value Name="Numeric" Value="0.05" />
            </Docs>            
          </Level_5>              
          <Level_5 Name="aa">            
            <Text>
              <Val Id="1"/>
            </Text>
          </Level_5>
          <Level_5 Name="aa">
            <Brand>
              <Value Name="Text" Value="2" />
              <Value Name="Number" Value="1" />
              <Value Name="Long" Value="3" />
            </Brand>
          </Level_5>
        </Level_4>
      </Level_3>
    </Level_2>    
  </Level_1>
</Root>

进行连接后,你应该有“”,LongNumberText,TextNumericPro 和预期产出是:

<Root att="x">
  <level_1 Name="NEW Level">    
    <level_2>      
      <Level_3 Name="nameLvl_3">        
        <Level_4>
          <Level_5 Name="aa">            
            <Text>
              <Val Id="1"/>
            </Text>
          </Level_5>
          <Level_5 Name="aa">
            <Brand>
          <Value Name="Long" Value="3" />
      <Value Name="Number" Value="1" />
              <Value Name="Text" Value="2" />             
            </Brand>
          </Level_5>
          <Level_5 Name="aa">
            <Brand>
              <Value Name="Text" Value="1" />
            </Brand>            
    <Docs>          
              <Value Name="Numeric" Value="0.05" />
              <Value Name="Pro" Value="2" />
            </Docs>            
          </Level_5>
        </Level_4>
      </Level_3>
    </Level_2>    
  </Level_1>
</Root>

我只能按/ Brand / Value / @ Name的第一个元素排序,但我不知道如何连接Brand和Docs中的其他属性这是代码imuisng:

<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="Level_3/Level_4/Level_5/Brand|Docs">
    <xsl:copy>
      <xsl:apply-templates>
        <xsl:sort select="@Name" data-type="text"/>
        <xsl:sort select="@Value" data-type="text"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

  <!--                                                    -->
  <xsl:template match="Level_2/Level_3/Level_4">
    <xsl:copy>  
      <xsl:apply-templates select="Level_5">
        <xsl:sort select="Brand|Docs/Value/@Name" data-type="text"/>
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

但是,我只是在品牌或文档内部的第一个元素,请任何帮助

1 个答案:

答案 0 :(得分:0)

在XPath 1.0表达式中可能有一种聪明的方法可以做到这一点,但我没有看到一个。更直接的方法是分两步处理数据。

首先编写一个执行近似标识转换的样式表:输入只是按原样写回输出,但是在每个Level_5元素上添加一个带有sort-key的属性,通过处理所有适当的孩子处于make-sort-key模式。

然后编写其他样式表并使用sort-key属性来控制排序(如果你不想让它再次丢弃它)。

关于另一个主题:匹配模式Level_3/Level_4/Level_5/Brand | Docs不等同于Level_3/Level_4/Level_5/Brand | Level_3/Level_4/Level_5/Docs。如果你的意思是后者,你需要一个不同的匹配模式。