XSL:在模板之间传递变量

bin*_*guy 13 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> 
Run Code Online (Sandbox Code Playgroud)

此模板将匹配:

<xsl:template match="folder">
  <xsl:param name="var1"/>
  <xsl:value-of select="$var1"/>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)

你看我想在匹配的模板中使用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>
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

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

C:xampplitehtdocsxamppimg

Rob*_*ney 32

您可以将参数传递给您通过其调用的命名模板<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>
Run Code Online (Sandbox Code Playgroud)

调用命名模板时,上下文节点是当前上下文.因此,要为子节点调用命名模板,您需要使用以下命令更改当前上下文<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>
Run Code Online (Sandbox Code Playgroud)

但是,在您的情况下,不需要传递参数,因为您尝试使用的变量是可从上下文节点导航的变量.并且您不需要使用所有这些变量(也不应该将变量命名为无效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>
Run Code Online (Sandbox Code Playgroud)

而且,我很想使用ancestor::structure[1]/@path而不是../../@path,因为它使意图更明确; 你的版本意味着" path从父元素的父元素中获取属性",而我的版本意味着"遍历祖先元素链,直到找到第一个命名的元素structure,并获取其path属性."


cr7*_*ph7 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>
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅10.1.2 Tunnel parametersXSLT 2.0规范中的部分.


一个扩展的例子

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

<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>
Run Code Online (Sandbox Code Playgroud)

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

请记住,tunnel="yes"属性声明必须同时出现在<xsl:param name="var1" tunnel="yes"/> AND和相应的<xsl:with-param name="var1" tunnel="yes" select="..."/>属性上.


Mad*_*sen 5

structure模板有两个问题:

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

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>
Run Code Online (Sandbox Code Playgroud)