元素列表测试

rjr*_*ray 5 xslt

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

v0_01,v0_10,v0_99
Run Code Online (Sandbox Code Playgroud)

而属性值每个看起来都非常像一个这样的值.(逗号是用于分隔值还是空格)并不重要 - 我现在选择了一个逗号,因为我计划通过命令行开关传递值xsltproc,并且使用空格需要引用参数,并且我很懒,不想输入额外的两个字符.)

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

Tom*_*lak 8

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

contains(concat(',' $list, ','), concat(',', $value, ','))
Run Code Online (Sandbox Code Playgroud)

将返回一个布尔值.或者您可以使用以下方法之一:

substring-before(concat('|,' $list, ',|'), concat(',', $value, ','))
Run Code Online (Sandbox Code Playgroud)

要么

substring-after(concat('|,' $list, ',|'), concat(',', $value, ','))
Run Code Online (Sandbox Code Playgroud)

如果您得到一个空字符串作为结果,$value不在列表中.

编辑:

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