0

我想知道是否有一种方法可以更方便地格式化测试表达式中的双连词。目前它看起来像这样:

<xsl:when test="local-name() = 'p' or local-name() = 'ul' or local-name() = 'sec'" >
    <xsl:call-template name="whatever" />
</xsl:when>

如果我想在这里测试大约 10 个元素,那么查找我已经添加的元素是非常不方便的。

2.0中有类似的东西吗?

<xsl:when test="local-name() = 'p'|'ul'|'sec'" >

更新:

在 2.0 中如何:

<xsl:when test="local-name() = ('p','ui','sec')" >
   <xsl:call-template name="whatever" />
</xsl:when>
4

2 回答 2

4

根本不要local-name()使用,使用正确的命名空间声明和节点测试。

这假定xmlns:n="..."您的 XSLT 中有一个声明。

<xsl:when test="self::n:p or self::n:ul or self::n:para">
    <xsl:call-template name="whatever" />
</xsl:when>

更好的是,使用模板匹配。

<xsl:template match="n:p | n:ul | n:para">
    <xsl:call-template name="whatever" />
</xsl:template>

如果您绝对必须使用字符串表达式 and local-name(),您可以使用index-of()

<xsl:when test="index-of(('p', 'ul', 'sec'), local-name())">
    <xsl:call-template name="whatever" />
</xsl:when>

* 之所以有效,是因为index-of()它在找到匹配项时返回一个非零数,并且非零数true在布尔上下文中计算为。

尽管我强烈建议不要在这种特殊情况下这样做,因为它与 XSLT 的设计原则相矛盾。

于 2013-08-05T11:11:16.897 回答
2

我同意 Tomalak 不与之合作,local-name()并且典型的方法是使用self::轴进行匹配:

<xsl:when test="self::n:p or self::n:ul or self::n:para">
    <xsl:call-template name="whatever" />
</xsl:when>

要回答您关于析取的具体问题,是的,XSLT 2.0 将以命名空间安全的方式准确地为您提供所需的东西,但我告诉我的 XSLT 学生,它确实并不比上述内置语法更优雅。

XSLT 2.0 允许测试singleton = ( sequence )true()在单例等于序列的任何成员时返回。因此,以下将返回true()

'b' = ( 'a', 'b', 'c' )

如果您在没有命名空间的情况下使用 HTML,则可以对序列使用以下单例测试:

test="node-name(.)=( QName('','p'), QName('','ul'), QName('','sec') )

在 XHTML 中,您可以使用以下内容:

<xsl:variable name="ns" select="'http://www.w3.org/1999/xhtml'"/>
<xsl:if test="node-name(.)=( QName($ns,'p'), QName($ns,'ul'), QName($ns,'sec') )"/>

但是,真的,我不认为这比:

xmlns:x="http://www.w3.org/1999/xhtml"
...
test="self::x:p or self::x:ul or self::x:para"

我想如果您使用 XHTML,您可以使用以下内容:

xpath-default-namespace="http://www.w3.org/1999/xhtml"
...
test="self::p or self::ul or self::para"

但是在我的专业工作中,当我保证我的输入只在一个命名空间中时,我只使用了每个 xpath-default-namespace。如果我的输入可以有多个命名空间,我从不使用它。

于 2013-08-05T12:13:07.823 回答