XSLT - 如何使用xsl引用当前节点值:select?

时间:2014-01-14 11:04:11

标签: xslt xsl-choose

我尝试创建一个变量,我可以在以后的模板中使用它:

<xsl:variable name="fc">
    <xsl:choose>
        <xsl:when test="self::node()='element1'">gray</xsl:when>
        <xsl:otherwise>red</xsl:otherwise>
    </xsl:choose>
</xsl:variable>

不幸的是它不起作用。

<xsl:template match="element1">
    <h1><font color="{$fc}"><xsl:value-of select="self::node()"/></font></h1>
</xsl:template>

我做错了什么?

以下是广泛的代码:

XML:

<root 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.test.com scheme.xsd" xmlns="http://www.test.com" xmlns:tst="http://www.test.com">
 <elementA>
    <elementB tst:name="name">
        <elementC tst:name="name">
            <element1> Test1 </element1>
            <element2> Test2 </element2>
         </elementC >
    </elementB> 
  </elementA>    
</root>

所有元素都是合格的,并且是命名空间“http://www.test.com”的一部分。

XSLT:

<xsl:template match="/">
<html>
<body><xsl:apply-templates select="tst:root/tst:elementA/tst:elementB/tst:elementC/tst:element1"/>
</body>
</html>

</xsl:template>
<xsl:variable name="var_fc">
<xsl:choose>
    <xsl:when test="local-name(.)='tst:element1'">gray</xsl:when>
    <xsl:otherwise>red</xsl:otherwise>
</xsl:choose>
</xsl:variable>

<xsl:template match="tst:element1">
<h2><font color="{$var_fc}"><xsl:value-of select="self::node()"/></font></h2>
</xsl:template>

因此,element1应该变为灰色,但它总是变为红色。

5 个答案:

答案 0 :(得分:1)

XSLT变量的设计是不可更改的。实际上它们可以被命名为常量。如果您的变量fc是全局创建的,它将使用根元素进行选择。您必须在实际模板中选择要针对当前元素进行测试。如果您只想将“红色”和“灰色”定义一次,请仅使用该文本内容创建两个变量,并使用这些变量而不是选择中的纯文本。

答案 1 :(得分:1)

你不能使用变量,因为xsl:variable的内容在定义时只被评估一次,而你想在每次引用变量时评估一些逻辑,在当前上下文中参考点。

相反,你需要一个名为的模板:

<xsl:template name="fc">
  <xsl:choose>
    <xsl:when test="local-name()='element1'">gray</xsl:when>
    <xsl:otherwise>red</xsl:otherwise>
  </xsl:choose>
</xsl:template>

或(更好)一对带模式的匹配模板,让模板匹配器完成工作:

<!-- match any node whose local name is "element1" -->
<xsl:template mode="fc" match="node()[local-name() = 'element1']">gray</xsl:template>

<!-- match any other node -->
<xsl:template mode="fc" match="node()">red</xsl:template>

如果您想使用此逻辑:

<h1>
  <font>
    <xsl:attribute name="color">
      <xsl:apply-templates select="." mode="fc" />
    </xsl:attribute>

看到您在样式表中映射了tst前缀,您可以直接检查名称,而不是使用local-name()谓词:

<xsl:template mode="fc" match="tst:element1">gray</xsl:template>
<xsl:template mode="fc" match="node()">red</xsl:template>

答案 2 :(得分:0)

也许这是一个错字:

<xsl:when test=self::node()='element1'">gray</xsl:when>

应该是:

<xsl:when test="self::node()='element1'">gray</xsl:when>

缺少引用。

答案 3 :(得分:0)

我认为不是test="self::node()='element1'"而是test="self::element1"test="local-name(.) = 'element1'"

答案 4 :(得分:0)

代码中的其他几个错误:

(1) self::node() = 'element1'

测试元素的内容是否为“element1”,而不是其名称是否为“element1”

(2) local-name(.)='tst:element1'

永远不会成立,因为节点的本地名称永远不会包含冒号。

有经验的用户经常使用模板规则编写此代码:

<xsl:template mode="var_fc" match="tst:element1">gray</xsl:template>
<xsl:template mode="var_fc" match="*">red</xsl:template>

然后

<xsl:apply-templates select="." mode="var_fc"/>