列表中元素测试 [英] Element-in-List testing

查看:26
本文介绍了列表中元素测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

For a stylesheet I'm writing (actually for a set of them, each generating a different output format), I have the need to evaluate whether a certain value is present in a list of values. In this case, the value being tested is taken from an element's attribute. The list it is to be tested against comes from the invocation of the stylesheet, and is taken as a top-level <xsl:param> (to be provided on the command-line when I call xsltproc or a Saxon equivalent invocation). For example, the input value may be:

v0_01,v0_10,v0_99

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

while the attribute values will each look very much like one such value. (Whether a comma is used to separate values, or a space, is not important-- I chose a comma for now because I plan on passing the value via command-line switch to xsltproc, and using a space would require quoting the argument, and I'm lazy-enough to not want to type the extra two characters.)

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

What I am looking for is something akin to Perl's grep, wherein I can see if the value I currently have is contained in the list. It can be done with sub-string tests, but this would have to be clever so as not to get a false-positive (v0_01 should not match a string that contains v0_011). It seems that the only non-scalar data-type that XSL/XSLT supports is a node-set. I suppose it's possible to convert the list into a set of text nodes, but that seems like over-kill, even compared to making a sub-string test with extra boundaries-checking to prevent false matches.

推荐答案

实际上,使用 XPath 字符串函数是正确的方法.您所要做的就是测试分隔符:

Actually, using XPath string functions is the right way to do it. All you have to make sure is that you test for the delimiters as well:

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

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

would return a Boolean value. Or you might use one of these:

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

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

如果结果为空字符串,则 $value 不在列表中.

If you get an empty string as the result, $value is not in the list.

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

@Dimitre's comment is correct: substring-before() (or substring-after()) would also return the empty string if the found string is the first (or the last) in the list. To avoid that, I added something at the start and the end of the list. Still contains() is the recommended way of doing this.

这篇关于列表中元素测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆