XSL:在模板之间传递变量

时间:2010-01-30 09:46:23

标签: xml xslt

是否可以将变量从一个父模板传递给其子元素?

<xsl:template match="structure">
  <xsl:variable name="var"><xsl:value-of select="@path" /></xsl:variable>
  <xsl:apply-templates select="folders">
    <xsl:with-param name="var1" select="'{var}'"/>
  </xsl:apply-templates>
</xsl:template> 

此模板将匹配:

<xsl:template match="folder">
  <xsl:param name="var1"/>
  <xsl:value-of select="$var1"/>
</xsl:template>

你看我想在匹配的模板中使用var作为var1。

我该如何做到这一点?

编辑: 结构是这样的:

<structure path="C:\xampplite\htdocs\xampp">
  <folders>
    <folder name="img">
      <date>01/28/10 21:59:00</date>
      <size>37.4 KB</size>
    </folder>
 </folders>
</structure>

EDIT2:

<xsl:template match="folder">
<xsl:variable name="var1"><xsl:value-of select="../../@path"/></xsl:variable>
<xsl:variable name="var2"><xsl:value-of select="@name" /></xsl:variable>
<xsl:variable name="var3"><xsl:value-of select="$var1"/>\<xsl:copy-of select="$var2"/>    </xsl:variable>
 <th colspan="2" align="left"  bgcolor="#FF5500"><a onclick="foo('{$var3}')"><xsl:value-of select="$var3"/></a></th>

在jscript函数中,字符串没有反斜杠。有谁知道为什么?

C:xampplitehtdocsxamppimg

4 个答案:

答案 0 :(得分:30)

您可以将参数传递给通过<xsl:call-template>调用的命名模板,例如:

<xsl:call-template name="name">
   <xsl:with-param name="param" select="xpathexpr"/>
</xsl:call-template>

<xsl:template name="name">
   <xsl:param name="param"/>
   ...
</xsl:template>

调用命名模板时,上下文节点是当前上下文。因此,要为子节点调用命名模板,您需要使用<xsl:for-each>

更改当前上下文
<xsl:for-each select="child">
   <xsl:call-template name="name">
      <xsl:with-param name="param" select="xpathexpr"/>
   </xsl:call-template>
</xsl:for-each>

但是,在您的情况下,不需要传递参数,因为您尝试使用的变量是可以从上下文节点导航的变量。而且你不需要使用所有这些变量(你也不应该给变量命名为var1无效):

<xsl:template match="folder">
   <xsl:variable name="linkarg" value="concat(../../@path, '\\', @name)"/>
   <xsl:variable name="linktext" value="concat(../../@path, '\', @name)"/>
   <th colspan="2" align="left"  bgcolor="#FF5500">
      <a onclick="foo('{$linkarg}')">
         <xsl:value-of select="$linktext"/>
      </a>
   </th>
</xsl:template>

另外,我很想使用ancestor::structure[1]/@path而不是../../@path,因为它使意图更明确;你的版本意味着“从父元素的父元素中获取path属性”,而我的版本意味着“遍历祖先元素链,直到找到第一个名为structure的元素,然后获取它{ {1}}属性。“

答案 1 :(得分:9)

使用XSLT 2.0时, 可以将参数传递给子模板,方法是将tunnel="yes"添加到呼叫站点的<xsl:with-param .../>,并添加</xsl:with-param .../>元素。被调用的模板也是如此。只是做:

<xsl:template match="folder">
  <xsl:param name="var1" tunnel="yes"/> <!-- note the 'tunnel="yes"' attribute here! -->
  <xsl:value-of select="$var1"/>
</xsl:template>

<xsl:template match="structure">
  <xsl:variable name="var"><xsl:value-of select="@path" /></xsl:variable>
  <xsl:apply-templates select="folders">
    <xsl:with-param name="var1" select="$var" tunnel="yes"/> <!-- note the 'tunnel' attribute here, too! -->
  </xsl:apply-templates>
</xsl:template>

有关详细信息,请参阅XSLT 2.0规范中的10.1.2 Tunnel parameters部分。


扩展示例

使用隧道参数,您甚至可以这样做:

<xsl:template match="structure">
   <!-- same as before -->
</xsl:template>

<xsl:template match="folder">
  <!-- Look, ma, no param declaration! -->
  <!-- ... -->
  <xsl:apply-templates select="date"/>
  <!-- ... -->
</xsl:template>

<xsl:template match="folder/date">
   <xsl:param name="var1" tunnel="yes"/>
   <xsl:value-of select="$var1"/>
</xsl:template>

由于tunnel属性,var1参数从初始模板通过所有中间模板传递到"folder/date"模板。

请记住,tunnel="yes" 对应的<xsl:param name="var1" tunnel="yes"/>属性必须同时包含<xsl:with-param name="var1" tunnel="yes" select="..."/>属性声明。

答案 2 :(得分:5)

structure模板存在两个问题:

  1. 您正在应用模板选择folders,但在folder上有模板匹配。将其更改为folder,或者如果您有folders模板,请确保它将var1参数值向下传递到folder模板。
  2. 你的with-param @select使用'{var}',它会选择该文字字符串{var}。如果您要选择var变量,请删除周围的引号和花括号,然后选择$var
  3. 已对structure模板应用更改:

    <xsl:template match="structure">
      <xsl:variable name="var"><xsl:value-of select="@path" /></xsl:variable>
      <xsl:apply-templates select="folder">
        <xsl:with-param name="var1" select="$var"/>
      </xsl:apply-templates>
    </xsl:template>
    

答案 3 :(得分:4)

电话的确切代码是:

<xsl:template match="structure">
  <xsl:variable name="var"><xsl:value-of select="@path" /></xsl:variable>
  <xsl:apply-templates select="folders/folder">
    <xsl:with-param name="var1" select="$var"/>
  </xsl:apply-templates>
</xsl:template>

访问根节点的@path属性的另一种方法是将模板修改为:

<xsl:template match="folder">
  <xsl:value-of select="../../../@path"/>
</xsl:template>