元素列表测试

时间:2008-12-10 13:30:18

标签: xslt

对于我正在编写的样式表(实际上是针对它们的一组,每个都生成不同的输出格式),我需要评估某个值是否存在于值列表中。在这种情况下,测试的值取自元素的属性。要测试的列表来自样式表的调用,并被视为顶级<xsl:param>(当我调用xsltproc或Saxon等效时,将在命令行中提供调用)。例如,输入值可以是:

v0_01,v0_10,v0_99

虽然属性值看起来非常像 one 这样的值。 (逗号是用于分隔值还是空格)并不重要 - 我现在选择了逗号,因为我计划通过命令行切换将值传递给xsltproc,并且需要使用空格引用这个论点,我很懒,不想输入额外的两个字符。)

我正在寻找的东西类似于Perl的grep,其中我可以看到我当前拥有的值是否包含在列表中。它可以通过子字符串测试来完成,但这必须是聪明的,以免得到误报(v0_01不应与包含v0_011的字符串匹配)。似乎XSL / XSLT支持的唯一非标量数据类型是节点集。我想可以将列表转换为一组文本节点,但这似乎是过度杀戮,甚至与使用额外边界检查进行子字符串测试相比,以防止错误匹配。

2 个答案:

答案 0 :(得分:8)

实际上,使用XPath字符串函数是正确的方法。所有你必须确保你也测试分隔符:

contains(concat(',' $list, ','), concat(',', $value, ','))

将返回一个布尔值。或者您可以使用以下其中一种:

substring-before(concat('|,' $list, ',|'), concat(',', $value, ','))

substring-after(concat('|,' $list, ',|'), concat(',', $value, ','))

如果您得到一个空字符串,$value不在列表中。

编辑:

@ Dimitre的评论是正确的:substring-before()(或substring-after())如果找到的字符串是列表中的第一个(或最后一个),也会返回空字符串。为避免这种情况,我在列表的开头和结尾添加了 something 。仍然contains()是推荐的方法。

答案 1 :(得分:4)

除Tomalak提供的XPath 1.0解决方案外,

使用XPath 2.0 可以标记值列表:

<强> exists(tokenize($list, ',')[. = $value])

当且仅当true()包含在值列表$value中时,

评估为$list