对于我正在编写的样式表(实际上是针对它们的一组,每个都生成不同的输出格式),我需要评估某个值是否存在于值列表中.在这种情况下,测试的值取自元素的属性.它要测试的列表来自样式表的调用,并被视为顶级
(当我调用xsltproc
或在Saxon等效调用时在命令行上提供).例如,输入值可以是:
v0_01,v0_10,v0_99
而属性值每个看起来都非常像一个这样的值.(逗号是用于分隔值还是空格)并不重要 - 我现在选择了一个逗号,因为我计划通过命令行开关传递值xsltproc
,并且使用空格需要引用参数,并且我很懒,不想输入额外的两个字符.)
我正在寻找的是类似于Perl的东西grep
,其中我可以看到我当前拥有的值是否包含在列表中.它可以通过子字符串测试来完成,但这必须是聪明的,以免得到误报(v0_01
不应该匹配包含的字符串v0_011
).似乎XSL/XSLT支持的唯一非标量数据类型是节点集.我想可以将列表转换为一组文本节点,但这似乎过度杀死,甚至与使用额外边界检查进行子字符串测试相比,以防止错误匹配.
实际上,使用XPath字符串函数是正确的方法.所有你必须确保你也测试分隔符:
contains(concat(',' $list, ','), concat(',', $value, ','))
将返回一个布尔值.或者您可以使用以下方法之一:
substring-before(concat('|,' $list, ',|'), concat(',', $value, ','))
要么
substring-after(concat('|,' $list, ',|'), concat(',', $value, ','))
如果您得到一个空字符串作为结果,$value
不在列表中.
编辑:
@Dimitre的评论是正确的:如果找到的字符串是列表中的第一个(或最后一个),则substring-before()
(或substring-after()
)也会返回空字符串.为了避免这种情况,我在列表的开头和结尾添加了一些内容.仍然contains()
是这样做的推荐方法.