xsl:如何在“匹配”中使用参数?

时间:2011-05-24 22:01:04

标签: xslt

我的xsl有一个参数

<xsl:param name="halfPath" select="'halfPath'"/>

我想在匹配中使用它

<xsl:template match="Element[@at1='value1' and not(@at2='{$halfPath}/another/half/of/the/path')]"/>

但这不起作用。我想一个不能在''里面使用参数。如何解决/解决这个问题?

4 个答案:

答案 0 :(得分:6)

好吧,你可以在模板中使用条件指令:

<xsl:template match="Element[@at1='value1']">
  <xsl:if test="not(@at2=concat($halfPath,'/another/half/of/the/path'))">
    .. do something
  </xsl:if>
</xsl:template>

您只需要知道此模板将处理满足第一个条件的所有元素。如果您有一个不同的模板来处理与第一个而不是第二个匹配的元素,那么请使用<xsl:choose>,并将另一个模板的主体放在<xsl:otherwise>块中。

或者,如果您可以切换到XSLT2处理器,XSLT2可以处理它。

答案 1 :(得分:5)

XSLT 1.0 W3C Specification forbids referencing variables/parameters inside a match pattern

  

“这是一个错误的价值   match属性包含一个   VariableReference“

XSLT 2.0中没有此限制,因此请使用XSLT 2.0

如果由于不可能的原因使用XSLT2.0是不可能的,请将<xsl:template>指令的完整主体放在<xsl:if>中,其中测试与匹配模式相同,等同于XSLT 2.0匹配模式,包含变量/参数引用。

在一个更复杂的情况下,您有多个模板匹配相同类型的节点但具有引用变量/参数的不同谓词,那么需要使用包装<xsl:choose>而不是包装{{ 1}}。

答案 2 :(得分:2)

本主题回答了我的问题,但Flynn1179提出的解决方案对我来说并不完全正确(YMMV)。所以按照比我更专业的人的建议来尝试它,但如果它不适合你,请考虑我是如何解决它的。我正在使用仅处理XSL版本1.0的xsltproc。

我需要匹配<leadTime hour="0024">,但请使用参数:<xsl:param name="hour">0024</xsl:param>。我找到: <xsl:if test="@hour='{$hour}'">无效,尽管此处和其他地方声明这是XSL v.1.0所必需的语法。 相反,更简单的<xsl:if test="@hour=$hour">完成了这项工作。

另一点:Dimitre上面建议你把模板放在if语句中。 xsltproc对此抱怨:相反,我将if语句放在模板中:

<xsl:template match="leadTime">
  <xsl:if test="@hour=$leadhour">
    <xsl:copy>
      <xsl:apply-templates select="node() | @*"/>
    </xsl:copy>
  </xsl:if>
</xsl:template>

答案 3 :(得分:1)

在XSLT 2.0中,您可以在匹配模式中引用全局变量,但语法比猜测更简单:

<xsl:template match="Element[@at1='value1' and 
              not(@at2=$halfPath/another/half/of/the/path)]"/>

而不是

<xsl:template match="Element[@at1='value1' and 
              not(@at2='{$halfPath}/another/half/of/the/path')]"/>

此外,语义不是您所期望的:在“/”的lhs上引用的变量必须包含节点集,而不是XPath表达式的片段。