XSLT 1.0当Test表达式等效于IN运算符时

时间:2014-07-16 19:33:02

标签: xml xslt expression xslt-1.0

我试图在下面的XSLT 1.0中做一些事情,而不是硬编码多个OR运算符,我想使用一个具有等同于IN运算符的逗号分隔值的变量

<xsl:variable name="CSV">userdefinedONe, userDefined two</xsl:variable>
<xsl:template....
  <xsl:choose...
   <xsl:when test="Name IN $CSV OR Name='hardcoded'>....
       DO SOMETHING
   ....
 </xsl:template>

3 个答案:

答案 0 :(得分:1)

有时,设置包含您正在测试的值的XML文档是合适的:

<days>
  <day>Monday</day>
  <day>Tuesday</day>
  <day>Wednesday</day>
</days>

然后使用

<xsl:when test="$day = document('days.xml')/days/day">

如果$ day等于任何<day>值,则返回true。如果有很多值,您还可以通过索引使用xsl:key:

来提高效率
<xsl:key name="d" match="day" use="."/>

<xsl:when test="key('d', $day)">

但是你必须要小心,因为在XSLT 1.0中,key()函数只能用于在包含上下文节点的文档中进行搜索。

答案 1 :(得分:0)

在没有一点帮助的情况下,使用XSLT 1.0没有优雅的方法来实现这一目标。

您可以使用exslt,类似这样的内容(未经测试的示例,只是为了说明这个想法):

<xsl:variable name="name" select="Name"/>
...
   <xsl:when test="str:tokenise(concat('hardcoded', ', ', $CSV))/token[text() = $name]">...

查看str:tokenise

的文档

你也可以在没有任何扩展的情况下实现这一点,但是它会被许多命名模板杂耍,当然不可读。当然,缺点是必须将依赖项添加到exslt。

答案 2 :(得分:0)

在XSLT 1.0中复制IN行为的一种方法是将$CSV的分隔符连接为$CSVName值的前缀和后缀,并测试是否使用Name函数在连接的$CSV中包含连接的contains()值:

<xsl:variable name="CSV">userdefinedONe, userDefined two</xsl:variable>
<xsl:variable name="delimiter" select="', '"/>
<xsl:choose>
    <xsl:when test="contains(concat($delimiter,$CSV,$delimiter), 
                             concat($delimiter, Name, $delimiter)) 
                    or Name='hardcoded' ">
        DO SOMETHING
        ....
    </xsl:when>
</xsl:choose>