1

我熟悉 XSLT 的基础知识,但我遇到了一个我似乎无法弄清楚的奇怪情况。对于这么长时间,我深表歉意,但我非常感谢您能提供的任何帮助。

我想根据排序后的 Brand/Value/@Name 和 Docs/Value/@Name 的串联对 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 中的其余属性,这是我正在使用的代码:

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

但我只是对 Brand 或 Docs 中的第一个元素进行排序,请提供任何帮助

4

1 回答 1

0

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

首先编写一个执行近似身份转换的样式表:输入只是按原样写回输出,但是在每个 Level_5 元素上添加一个带有排序键的属性,通过处理所有适当的子元素来构造一个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. 如果你的意思是后者,你需要一个不同的匹配模式。

于 2012-11-01T00:48:27.203 回答