2012-02-12 47 views
6

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

任何想法将不胜感激。

感谢

回答

13

有什么办法我只能申报格洛巴l变量,然后在第一个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

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

的希望,正确的结果产生

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

那么我如何得到两个不同领域的价值以后使用? – Julian 2013-11-19 15:44:37

+0

只需定义两个变量并将其初始化为相应的“字段”即可。关于“以后” - 功能语言中没有这样的事情。评估可以以任何顺序和/或并行进行 – 2013-11-19 17:02:29

0

xsl:for-each是不是在这个意义上forforeach循环过程中的语言都有一个循环,使任何问题谈论的循环是很难理解,更难以回答。

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

你写
0
  1. , 'XSL是一个程序郎' ...那么,它不是。这是一个声明语言 ..
  2. 变量与其声明一起分配,变量不会改变!
  3. 通常我们按照递归调用使用call-template PARAMS传递给他们的模板..(这就像递归函数与过程式语言传递参数调用)
    这是处理计数了一个方法和条件循环等。

我们将竭诚为您服务柜面如果您提及与示例XML的确切情况,以及你期待出来的:)输出

+0

知道这是3年前,但他写道:*我知道XSLT是不是程序语言* ... – LuckyLikey 2015-05-06 13:57:32

+1

@LuckyLikey,检查问题的编辑历史,迪米特里已经纠正它。早些时候它是“我知道XSLT是一种程序语言” – 2015-05-12 09:26:13

+0

你是对的..我很抱歉得到一个+1 – LuckyLikey 2015-05-12 09:35:11