是否可以将变量从一个父模板传递给其子元素?
<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
答案 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
模板存在两个问题:
folders
,但在folder
上有模板匹配。将其更改为folder
,或者如果您有folders
模板,请确保它将var1
参数值向下传递到folder
模板。'{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>
答案 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>