XPath使用谓词选择多个元素

11

我有一个XPath查询,它正在做我想要的事情,即使用给定的谓词选择“surname”和“given-names”的并集(实际上是“或者”,但并集可以正常工作):

/header/authors/surname[./text() and @id='1']
|
/header/authors/given-names[./text() and @id='1']

然而,这对我来说似乎过于冗长,我觉得应该有更简洁的方法,例如:

/header/authors/(surname|given-names)[./text() and @id='1']

......但是这个版本不是有效的XPath。

有没有人能告诉我如何更简洁地编写原始XPath表达式,而不需要两次编写完整路径?

谢谢

Richard


“either/or”是什么意思? - user357812
@Alejandro:给定一个id,所需的元素可能是'surname'或'given-names'。这就是我想说的。我认为我需要的是联合。 - Richard Corfield
3个回答

27

首先,这是有效的XPath 2.0:

/header/authors/(surname|given-names)[./text() and @id='1'] 

其次,这是XPath 1.0:

/header/authors/*[self::surname|self::given-names][text()][@id='1'] 

1
这很棒,我本来要点赞的。然而,在XPath 1.0版本中最好不要在谓词内使用|。正确的运算符是or。在这种情况下,表达式仍然选择所需的节点,但在其他情况下,用|替换or不能产生等效的表达式。无论如何,还是点个赞。 - Dimitre Novatchev
1
@Dimitre:你对于 | 并集运算符的理解是正确的,但是在 这种情况下 我使用了它,因为两个术语都是节点集(而且简洁是关键)。谓词序列也是同样的道理。 - user357812
这个答案解释了为什么我觉得我应该能够使用(surname|given-names)(当前项目不使用XPath 2.0),并提供了一个很好的XPath 1.0替代方案。谢谢。 - Richard Corfield

4

你能行吗?

/header/authors/*[(name() = "surname" or name()="given-names") and ./text() and @id='1'] 

谢谢你的回答。这确实避免了两次写路径,但与我想象中的相比仍然有些笨重。 - Richard Corfield

3
除了Alejandro和Seva的好答案外,另一个选择是:
(/header/authors/surname | /header/authors/given-names)[text() and @id='1']

这在XPath 1.0中是有效的。虽然有点冗余,但比你问题中冗长的版本更为简洁。
另一种选择是声明一个变量用于姓氏元素,另一个变量用于名字元素,然后……
($surnames | $given-names)[text() and @id='1']

那可能会更长,但比上面容易阅读。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接