如何在XPath中使用AND运算符?

5

XML就像

 <a id="1">
   <b>value1</b>
   <b>value2</b>
 </a>

我希望编写 XPath 以查找包含两个 <b> 子节点并且这些子节点的值分别为 value1value2<a> 元素的 id。我尝试使用以下条件编写 XPath:
$xml->xpath('*[b=value1] | *[b=value2]');  

value1value2存在于<b>节点中,但是我第一次使用XPath无法精确获取。


这是一个不好的想法,通过值来查找元素,因为可以轻松地找到获取值元素的普通元素。 - Naumov
@kjhughes 抱歉,但我真的不明白为什么要按值搜索元素。通常,元素通过ID或超链接进行搜索以获取值元素,对我的英语表示抱歉。我认为阅读者可能无法理解我的评论。 - Naumov
@Naumov:你说得对,基于@id的搜索可能更可取,在这种情况下看起来是可能的,但让我们给予OP怀疑的好处,他的真实情况可能更加复杂,而这只是一个简化的情况。根据元素值搜索并不本质上是一个“坏主意”。谢谢。 - kjhughes
@kjhughes 对不起,我的英语不太好,因为我在翻译俄语到英语和英语到俄语的时候可能会出错。再次道歉并致以最好的问候。 - Naumov
2个回答

12

以下是XPath表达式:

//a[b = 'value1' and b = 'value2']/@id

将选择具有子元素 b 的所有 a 元素的 id 属性,其中一个子元素 b 的字符串值等于 value1 AND 另一个子元素 b 的字符串值等于 value2,如所请求。


1
啊啊啊 - 我卡在这里了...就是XPath查询中@id的位置。比我的答案整洁多了(我现在会删除它);) - CD001
谢谢。它运行良好。但是当有更多元素时,它不像预期的那样工作。例如,在<a>标签中还有其他元素,如<c></c>。 - hrishi
不用谢。你可以针对 c 添加 and c = 'value3',或者可以添加 and * = 'value3' 来匹配 a 的任何子元素。如果这无法满足您的需求,请提出一个新问题,并确保展示应该匹配和不应该匹配的例子。谢谢。 - kjhughes

-3

contains 函数可以实现此功能。

$nodes = $xpath->query("//b[contains(., 'value1')] | //b[contains(., 'value2')]");

然后,获取父级ID

$parent_id = $nodes->item(0)->parentNode->getAttribute("id");

一个带有HTML的演示 在这里

这个答案是错误的。它没有捕捉到要求的AND概念,并且它在应该使用字符串相等性测试的地方使用了字符串包含测试。 - kjhughes
使用contains()而不是"="是那些没有阅读规范的人常犯的错误。 - Michael Kay

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