以空格分隔的文本节点的 XPath 条件

XPath condition for a whitespace separated text node

使用这样的元素:

<element>one two two-and-a-half three four</element>

有没有一种方法可以定义 XPath 1.0 条件(计算为布尔值)来检查元素的文本节点是否包含一个或多个空格分隔值,例如 "two""three",假设这些值可能以任何顺序出现?这些值还可能包含其他值的一部分,如 "two""two-and-a-half".

所示

这个问题是关于 XPath 编码模式的,并且假定没有特定的编程 language/tool 上下文。为了论证,您可以假设 element 已经是表达式的上下文节点并且

. = 'one two two-and-a-half three four'

因此会计算为 true

不幸的是,在 XPath 1.0 中很难处理一个表达式中的字符串操作,您可能不会非常喜欢下面的解决方案。如果您能够使用 XPath 2.0,这将变得简单 .[tokenize(., ' ')[. = ('two', 'three', 'four')]]

XPath 1.0

如果没有像 XSLT 这样的宿主语言的帮助,我们将陷入重复。然而,如果我们要忽略没有前导或尾随 space 的事实,这是一个可能但有点幼稚的解决方案:

.[contains(., 'two ') and contains(., ' two')]

在此基础上,我们可以添加 leading/trailing space,创建一个有点笨拙但可行的 XPath 1.0 解决方案:

.[contains(concat(' ', ., ' '), ' two ')]

在此表达式中,concat(...) 会将当前元素的字符串值与前后的 space 连接起来。这确保如果我们测试给定的文本,示例中的 'two',只有当至少有一个前导 space 和一个尾随 space 时,它才会为真。

在此基础上,我们可以进一步扩展它以测试多个条件:

.[contains(concat(' ', ., ' '), ' two ') and contains(concat(' ', ., ' '), ' three ')]

备注

鉴于您在原始问题中所说的重点已经放在 element 上,我在所有表达式的开头都加上了一个前导点。只需将其替换为 select 表达式 selects element.