使用XSLT 2.0在xsl:variable中导航和排序XML

时间:2010-10-19 20:57:07

标签: xml xslt xslt-2.0

'formslist'变量中的XML是使用apply-templates创建的。此代码段来自2.0样式表。

<xsl:variable name="formlist">
    <forms>
     <FORM form_name="form1" print_seq="1200"/>
     <FORM form_name="form2" print_seq="1500"/>
     <FORM form_name="form3" print_seq="9000"/>
     <FORM form_name="form4" print_seq="5500"/>
    </forms>
</xsl:variable>

    <xsl:for-each select="$formslist/*">
     <xsl:sort select="FORM/@print_seq"/>
     <xsl:copy-of select="."/>
   </xsl:for-each>  

XML输出正常,但没有按print_seq

排序

2 个答案:

答案 0 :(得分:0)

这是因为$formslist/*选择forms元素。

您可以将$ formlist声明为:

<xsl:variable name="formlist" as="element()"> 
    <forms> 
     <FORM form_name="form1" print_seq="1200"/> 
     <FORM form_name="form2" print_seq="1500"/> 
     <FORM form_name="form3" print_seq="9000"/> 
     <FORM form_name="form4" print_seq="5500"/> 
    </forms> 
</xsl:variable> 

但是你会丢失副本中的forms元素。

其他解决方案将是具有排序的身份规则。这个样式表:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:variable name="formlist">
        <forms>
            <FORM form_name="form1" print_seq="1200"/>
            <FORM form_name="form2" print_seq="1500"/>
            <FORM form_name="form3" print_seq="9000"/>
            <FORM form_name="form4" print_seq="5500"/>
        </forms>
    </xsl:variable>
    <xsl:template match="/">
        <xsl:apply-templates select="$formlist" mode="copy"/>
    </xsl:template>
    <xsl:template match="node()|@*" mode="copy">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*" mode="copy">
                <xsl:sort select="self::FORM/@print_seq"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

输出:

<forms>
    <FORM form_name="form1" print_seq="1200"/>
    <FORM form_name="form2" print_seq="1500"/>
    <FORM form_name="form4" print_seq="5500"/>
    <FORM form_name="form3" print_seq="9000"/>
</forms>

答案 1 :(得分:0)

<xsl:variable name="formlist">    
    <forms>    
     <FORM form_name="form1" print_seq="1200"/>    
     <FORM form_name="form2" print_seq="1500"/>    
     <FORM form_name="form3" print_seq="9000"/>    
     <FORM form_name="form4" print_seq="5500"/>    
    </forms>    
</xsl:variable>    

    <xsl:for-each select="$formslist/*">    
     <xsl:sort select="FORM/@print_seq"/>    
     <xsl:copy-of select="."/>    
   </xsl:for-each>

此代码的问题

  1. formlist变量没有指定类型,默认情况下其类型为document-node()这意味着$formlist/*选择单个顶部元素{ {1}}并对单个元素进行排序会产生这个元素(未更改)。如果变量的类型已指定为forms,则可以避免此问题。

  2. 即使上述问题已解决,指定的排序键as="element()"也不正确 - FORM/@print_seq元素没有{{1孩子。正确的排序键只有:FORM

  3. 即使上面的前两个问题不存在,排序仍然不正确,因为排序键类型被视为字符串而不是数字。正确的FORM指令需要指定@print_seq,或者排序键本身应指定为<xsl:sort>

  4. <强>解决方案

    只需使用

    data-type="number"

    将此转换应用于任何XML文档(未使用)时,会生成所需的正确结果

    xs:integer(@print_seq)