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



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

<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>

因此,元素 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>

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

也许这是一个错字:

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

应该是:

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

缺少报价。

我认为你想要的不是test="self::node()='element1'" test="self::element1"test="local-name(.) = 'element1'".

代码中的其他几个错误:

(1) self::node() = 'element1'
测试元素的内容是否为"元素1

",而不是测试其名称是否为"元素1"

(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"/>

最新更新