xslt变量范围及其用法

时间:2012-02-12 15:19:58

标签: xslt

我正在学习xslt并且有一个关于如何在diff中使用xslt变量的问题。对于每个循环。我知道xslt不是一个过程语言,因此在for循环中声明的变量不能在另一个循环中访问。但有没有什么方法可以声明全局变量然后在第一个for循环中分配一些值并在第二个循环中使用该变量?

任何想法都将受到高度赞赏。

由于

3 个答案:

答案 0 :(得分:13)

  

有什么方法我可以声明全局变量然后分配一些   第一个for循环中的值,并在第二个循环中使用该变量?

xsl:variable中为xsl:for-each分配值(当然这只是初始化)的方法是将xsl:for-each包含在变量的正文中

这是一个完整的例子:

<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="/*">
     <xsl:variable name="vMax">
       <xsl:for-each select="num">
        <xsl:sort data-type="number" order="descending"/>

        <xsl:if test="position() = 1">
         <xsl:value-of select="."/>
        </xsl:if>
       </xsl:for-each>
     </xsl:variable>

     Values close to the maximum:
<xsl:text/>

       <xsl:for-each select="num">
        <xsl:if test="not($vMax - . > 3) ">
         <xsl:value-of select="."/>
         <xsl:text>&#xA;</xsl:text>
        </xsl:if>
       </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

将此转换应用于以下XML文档 ...

<nums>
  <num>01</num>
  <num>02</num>
  <num>03</num>
  <num>04</num>
  <num>05</num>
  <num>06</num>
  <num>07</num>
  <num>08</num>
  <num>09</num>
  <num>10</num>
</nums>

...它首先定义一个vMax变量,该变量从其正文中包含的xsl:for-each中获取其值。

然后在第二个vMax中使用xsl:for-each变量来输出与计算出的最大值“接近”的所有数字。

产生了想要的正确结果

     Values close to the maximum:
07
08
09
10

还可以通过使用递归调用的命名模板来模拟“赋值”具有不同值的变量,并将“新值”作为参数传递给被调用模板

以下是显示此技术的示例。这里我们计算节点集节点中包含的值的最大值。每次我们访问节点集中的下一个节点时,都会将当前最大值与此值进行比较,如果需要,新的最大值将成为下一个节点的值。然后我们递归地调用相同的模板,将当前最大值传递给新的最大值:

<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="/*">
  <xsl:call-template name="max">
    <xsl:with-param name="pList" select="*"/>
  </xsl:call-template>
 </xsl:template>

 <xsl:template name="max">
   <xsl:param name="pMax" select="-99999999"/>
   <xsl:param name="pList"/>

   <xsl:choose>
     <xsl:when test="$pList[1]">
       <xsl:variable name="vnewMax" select=
       "$pMax * ($pMax >= $pList[1])
       +
        $pList[1] * not($pMax >= $pList[1])
       "/>

       <xsl:call-template name="max">
        <xsl:with-param name="pMax" select="$vnewMax"/>
        <xsl:with-param name="pList" select="$pList[position() > 1]"/>
       </xsl:call-template>
     </xsl:when>
     <xsl:otherwise>
       <xsl:value-of select="$pMax"/>
     </xsl:otherwise>
   </xsl:choose>
 </xsl:template>
</xsl:stylesheet>

将此转换应用于同一XML文档(上图)时,会生成所需的正确结果

10

答案 1 :(得分:0)

xsl:for-each不是程序语言中存在forforeach循环的循环,因此任何讨论循环的问题都难以理解且难以回答。

如果你想在XSLT中使用全局变量,你可以这样做,但你可以将一个值绑定到你声明它的变量(即全局),你不能在for-each中稍后赋值。正如你似乎想做的那样。

答案 2 :(得分:0)

  1. 你写过,' XSL是一个程序性的lang '..好吧,它不是。这是一种陈述语言 ..
  2. 变量与其声明一起分配,变量不会改变!
  3. 通常我们使用call-template跟踪模板的递归调用将params传递给它们。(这就像在过程语言中传递参数的递归函数调用一样
    这是处理计数和条件循环等的一种方法。
  4. 如果您提及Sample XML的确切方案以及您期望的输出,我们很乐意帮助您:)