我尝试创建一个变量,我可以在以后的模板中使用它:
<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"/>