我想在xpath表达式中使用xslt参数的值。具体而言,作为not()
表达式<xsl:if
调用的一部分。
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- my_param contains a string '/foo/bar', passed in from ant -->
<!-- the 'no' is just a default value -->
<xsl:param name="my_param">no</xsl:param>
<xsl:variable name="var_myparam" select="$my_param" />
<!-- ... -->
<!-- this works -->
<xsl:if test="not(/foo/bar)" /> <!-- expression returns boolean true -->
<!-- ... -->
</xsl:if>
<!-- I can't figure out how to do this the right way -->
<!-- None of these appear to work -->
<xsl:if test="not($var_myparam)" /> <!-- expression returns boolean false -->
<!-- ... -->
</xsl:if>
<xsl:if test="not({$var_myparam})" /> <!-- complains Required attribute 'test' is missing -->
<!-- ... -->
</xsl:if>
<xsl:if test="not({$myparam})" /> <!-- complains Required attribute 'test' is missing -->
<!-- ... -->
</xsl:if>
<xsl:if test="not($myparam)" /> <!-- expression returns boolean false -->
<!-- ... -->
</xsl:if>
</xsl:transform>
我有点不清楚在xslt样式表中创建动态xpath表达式的正确语法是什么。对于参数,变量以及两者的扩展方式之间的差异,我也有点模糊。例如,有了参数,我知道有时我需要括号,有时我不需要。
<!-- when creating an element, it seems I need brackets -->
<xsl:element name="{$my_param}" />
<!-- when selecting an element value for the output stream, no brackets are needed -->
<xsl:value-of select="$my_param"/>
非常感谢任何一般/特定的帮助。
答案 0 :(得分:5)
结帐http://www.exslt.org/。 具体来看动态:评估模块。
答案 1 :(得分:4)
XSLT不支持XPath的动态评估 - 这就是为什么你需要使用像EXSLT evaluate
这样的扩展函数来实现它。
如果您不想使用扩展函数(并且有充分的理由不这样做),另一种可能性是在执行转换之前查询输入文档的DOM,并将节点集作为参数传递给转换
修改强>
关于那些花括号:这些是属性值模板(AVT)。这些在XSLT转换中在语义上是等效的:
<foo>
<xsl:attribute name="bar">
<xsl:value-of select="XPathExpression"/>
</xsl:attribute>
</foo>
<foo bar="{XPathExpression}"/>
第二个只是第一个的快捷方式。
关于变量和参数:从语法上讲,变量和参数之间没有区别;在XPath表达式中引用$foo
的任何地方,只要foo
或xsl:variable
定义xsl:param
,它就会一样。
两者之间的区别在于它们是如何填充的。变量填充在xsl:variable
声明中。使用xsl:param
在命名模板中声明参数,但是使用xsl:with-param
,使用<xsl:call-template name="foo">
<xsl:with-param name="bar" select="XPathExpression"/>
</xsl:call-template>
<xsl:template name="foo">
<xsl:param name="bar"/>
...
调用命名模板时填充它们,例如:
xsl:stylesheet
这是一个很奇怪的例外,它是<xsl:stylesheet ...
<xsl:param name="system-date"/>
...
的孩子的参数。没有办法在变换中填充这些参数;那些是外部填充的,由任何(特定于环境)机制调用转换。
一个非常常见的用例是弥补XSLT没有系统日期功能的事实。所以你会看到类似的东西:
XsltArgumentList args = new XsltArgumentList();
args.AddParam("system-date", "", DateTime.Now.ToString("s"));
xslt.Transform(input, args, result);
然后,在调用转换时,就像这样(在C#中):
{{1}}
答案 2 :(得分:3)
尝试一些变体:
<xsl:if test="not($var_myparam = 'no'))">
</xsl:if>
问题在于XPath如何评估布尔值。在XPath中,任何非空字符串都将计算为true。结帐write-up about xpath booleans。
至于你的其他问题......变量和参数在XPath表达式中的作用相同。两者都以$ var的形式引用。
对于名为“select”的任何XSLT属性,您不需要括号。括号用于所谓的“属性值模板”。当XSLT期望字符串时,您可以使用它们,例如:
<xsl:template match="name-a">
<xsl:variable name="old-name" select="name(.)" />
<name-b old-name="{$old-name}" new-attribute="hello" />
</xsl:template>