php xpath query to get parent node based on value in repeating child nodes
我有一个XML文件,其结构如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | <pictures> <picture> <description></description> <facts> <date></date> <place>Unites States</place> </facts> <people> <person>John</person> <person>Sue</person> </people> </picture> <picture> <description></description> <facts> <date></date> <place>Canada</place> </facts> <people> <person>Sue</person> <person>Jane</person> </people> </picture> <picture> <description></description> <facts> <date></date> <place>Canada</place> </facts> <people> <person>John</person> <person>Joe</person> <person>Harry</person> </people> </picture> <pictures> |
在一个案例中,我需要在place="canada"中搜索图片。我有一个XPath可以做到这一点,比如:
1 2 | $place ="Canada"; $pics = ($pictures->xpath("//*[place='$place']")); |
这将拉动整个"图片"节点,因此我可以显示标题、描述等。我还有另一个需要找到所有图片,其中person=$person。我使用与上面相同的类型查询:
1 2 | $person ="John"; $pics = ($pictures->xpath("//*[person='$person']")); |
在本例中,查询显然知道John有两张图片,但我没有得到其他节点的任何值。我猜这和重复的子节点有关系,但是我不知道如何重新构造xpath来为每个我匹配的人提取所有图片节点。我尝试使用属性而不是值(并相应地修改了查询),但得到了相同的结果。有人能告诉我这里缺少什么吗?
让我们先替换变量。这就把PHP从图片中去掉了。问题只是正确的xpath表达式。
匹配具有子元素节点
这是
获取图片节点略有不同:
这将选择任何深度与条件匹配的图片节点。
将返回与所提供的XML相同的结果,但更具体,只匹配作为document元素子级的
现在验证
您甚至可以将这两个条件结合起来:
下面是一个小演示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | $element = new SimpleXMLElement($xml); $expressions = [ '//*[place="Canada"]', '//picture[facts/place="Canada"]', 'picture[facts/place="Canada"]', 'picture[people/person="John"]', 'picture[facts/place="Canada" and people/person="John"]', ]; foreach ($expressions as $expression) { echo $expression," ", str_repeat('-', 60)," "; foreach ($element->xpath($expression) as $index => $found) { echo '#', $index," ", $found->asXml()," "; } echo" "; } |
提示:在xpath表达式中使用dyamic值。xpath 1.0中的字符串文本不支持任何类型的转义。变量中的引号可能会破坏表达式。看看这个答案。