我想应用一个模式取决于变量值的模板。
<xsl:variable name="mode" select="@attribute"/>
<xsl:apply-templates mode="{$mode}"/>
我收到无法编译样式表的错误。mode 的值应该是 QName,但它是“{$mode}”。
是否有可能使用依赖于变量的模式?
您必须使用基于表达式的特定模式的唯一选项是使用
<xsl:choose>
<xsl:when test="@attribute = 'foo'">
<xsl:apply-templates mode="bar"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates/>
</xsl:otherwise>
</xsl:choose>
或与xsl:if
. mode
属性值本身需要在 XSLT 1.0 中为 a ,QName
在 XSLT 2.0 中分别允许 aQName
或特殊标记,如#current
or #default
'。但是您无法mode
在运行时计算值。
mode不是属性值模板 (AVT) 的有效候选者。你根本无法做到这一点。
[定义:在被指定为属性值模板的属性中,例如文字结果元素的属性,可以通过用大括号({})将表达式括起来来使用表达式]。
模式在规范中没有被指定为 AVT,所以你不能这样做。
我收到无法编译样式表的错误。mode 的值应该是 QName,但它是“{$mode}”。
是否有可能使用依赖于变量的模式?
不,任何 XSLT 版本(1.0、2.0 或 3.0)都不支持此功能。
当您尝试模拟高阶函数 (HOF) 时,您可以使用FXSL的基本原理在 XSLT 1.0 中执行此操作。
FXSL 1.x 是一个用纯 XSLT 1.0 编写的模板库,支持/模拟 HOF。
这是基于这些原则的完整解决方案:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://fxsl.sf.net" exclude-result-prefixes="f">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<f:inc/>
<f:double/>
<xsl:variable name="vModeInc" select="document('')/*/f:inc[1]"/>
<xsl:variable name="vModeDouble" select="document('')/*/f:double[1]"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<nums>
<xsl:apply-templates select="$vModeInc">
<xsl:with-param name="pNodes" select="node()"/>
</xsl:apply-templates>
</nums>
==============
<nums>
<xsl:apply-templates select="$vModeDouble">
<xsl:with-param name="pNodes" select="node()"/>
</xsl:apply-templates>
</nums>
</xsl:template>
<xsl:template match="f:inc">
<xsl:param name="pNodes"/>
<xsl:apply-templates select="$pNodes" mode="incr"/>
</xsl:template>
<xsl:template match="f:double">
<xsl:param name="pNodes"/>
<xsl:apply-templates select="$pNodes" mode="double"/>
</xsl:template>
<xsl:template match="num" mode="incr">
<num><xsl:value-of select=".+1"/></num>
</xsl:template>
<xsl:template match="num" mode="double">
<num><xsl:value-of select=".*2"/></num>
</xsl:template>
</xsl:stylesheet>
当此转换应用于以下 XML 文档时:
<nums>
<num>01</num>
<num>02</num>
<num>03</num>
<num>04</num>
<num>05</num>
<num>06</num>
<num>07</num>
<num>08</num>
<num>09</num>
<num>10</num>
</nums>
产生所需的正确结果- 以nums/num
两种可用模式中的一种(每种)处理的元素,具体取决于指定的变量 - $vModeInc
(每个值加 1)或$vModeDouble
(每个值乘以 2):
<nums>
<num>2</num>
<num>3</num>
<num>4</num>
<num>5</num>
<num>6</num>
<num>7</num>
<num>8</num>
<num>9</num>
<num>10</num>
<num>11</num>
</nums>
==============
<nums>
<num>2</num>
<num>4</num>
<num>6</num>
<num>8</num>
<num>10</num>
<num>12</num>
<num>14</num>
<num>16</num>
<num>18</num>
<num>20</num>
</nums>