首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >xslt变量作用域及其用法

问xslt变量作用域及其用法
EN

Stack Overflow用户
提问于 2012-02-12 23:19:58
回答 3查看 24.6K关注 0票数 9

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

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

谢谢

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-02-13 21:42:45

有没有什么方法可以声明全局变量,然后在第一个

循环中赋值,然后在第二个for循环中使用该变量?

在xsl:variable xsl:for-each**,中为xsl:variable赋值(当然,这只是初始化)的方法是在变量的主体中包含** xsl:for-each 。

下面是一个完整的示例:

代码语言:javascript
复制
<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>

在以下文档上应用此转换时...

代码语言:javascript
复制
<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>

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

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

生成所需的正确结果

代码语言:javascript
复制
     Values close to the maximum:
07
08
09
10

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

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

代码语言:javascript
复制
<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文档(如上)时,将生成所需的正确结果

代码语言:javascript
复制
10
票数 16
EN

Stack Overflow用户

发布于 2012-02-13 00:14:37

从过程化语言中存在的for或foreach循环的意义上讲,xsl:for-each不是循环,所以任何关于循环的问题都很难理解,也更难回答。

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

票数 0
EN

Stack Overflow用户

发布于 2012-02-13 21:32:24

  1. 你已经写过,'XSL是一种过程语言‘..嗯,不是的。它是一种声明性语言参数..变量是随声明一起赋值的,变量‘t change!
  2. Usually我们遵循递归调用,使用call-template将参数传递给模板。(这就像过程化语言中传递参数的递归函数调用一样)

这是处理计数和条件循环等的一种方法。

如果您提到示例XML的确切场景以及您期望的输出,我们将很乐意为您提供帮助:)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9249913

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档