我一直在努力想象这一天,但我似乎无法让它发挥作用。
我们说我有一个名为test.xml
的XML文件:
<root>
<itemList>
<item>
<name>A</name>
<type>AAA</type>
</item>
<item>
<name>B</name>
<type>BBB</type>
</item>
<item>
<name>C</name>
<type>CCC</type>
</item>
</itemList>
</root>
从PHP开始,我使用SimpleXMLElement
查找文本为BBB
的节点。
<?php
$xmlStr = file_get_contents('test.xml');
$xml = new SimpleXMLElement($xmlStr);
$res = $xml->xpath('//type[contains(text(), "BBB")]/parent::*');
echo "{$res[0]->name} ({$res[0]->type})";
// Result: B (BBB)
现在,我想找到preceding-sibling
的{{1}}节点,并获取parent
个节点&#39}。像child
这样的值,但我无法弄清楚如何做到这一点。
任何帮助都会很棒。
感谢。
答案 0 :(得分:2)
要获取最近的前一个兄弟,请使用此XPath查询:
//type[contains(text(), "BBB")]/parent::item/preceding-sibling::item[1]
您需要将谓词设置为1,以便选择最近的兄弟姐妹。否则,您将始终获得第一个兄弟(例如,如果您删除[1]
谓词,则会获得AAA
和BBB
的{{1}}元素<) / p>
请注意,通配符不是必需的,因为您可能已经知道标记是什么。
CCC
结果
A(AAA)
B(BBB)
为了进一步说明使用谓词的必要性,请看一下:
$xml = "<root>
<itemList>
<item>
<name>A</name>
<type>AAA</type>
</item>
<item>
<name>B</name>
<type>BBB</type>
</item>
<item>
<name>C</name>
<type>CCC</type>
</item>
</itemList>
</root>";
$xml = new SimpleXMLElement($xml);
$res = $xml->xpath('//type[contains(text(), "BBB")]/parent::item/preceding-sibling::item[1]');
echo "{$res[0]->name} ({$res[0]->type})".PHP_EOL;
$res = $xml->xpath('//type[contains(text(), "CCC")]/parent::item/preceding-sibling::item[1]');
echo "{$res[0]->name} ({$res[0]->type})";
结果
$xml = "<root>
<itemList>
<item>
<name>A</name>
<type>AAA</type>
</item>
<item>
<name>B</name>
<type>BBB</type>
</item>
<item>
<name>C</name>
<type>CCC</type>
</item>
<item>
<name>C</name>
<type>DDD</type>
</item>
</itemList>
</root>";
$xml = new SimpleXMLElement($xml);
$res = $xml->xpath('//type[contains(text(), "DDD")]/parent::item/preceding-sibling::item');
var_dump($res);
看看,无论您使用查询选择哪个元素,最远的兄弟姐妹首先总是在列表中(最接近最后一个)?因此,为了模拟使用谓词,您还可以获得最接近的兄弟,只需选择数组中的最后一个元素(注意没有array (size=3)
0 =>
object(SimpleXMLElement)[2]
public 'name' => string 'A' (length=1)
public 'type' => string 'AAA' (length=3)
1 =>
object(SimpleXMLElement)[3]
public 'name' => string 'B' (length=1)
public 'type' => string 'BBB' (length=3)
2 =>
object(SimpleXMLElement)[4]
public 'name' => string 'C' (length=1)
public 'type' => string 'CCC' (length=3)
谓词):
[1]
答案 1 :(得分:1)
请参阅演示https://implode.io/q9OOSC
$xmlStr = <<<XML
<root>
<itemList>
<item>
<name>A</name>
<type>AAA</type>
</item>
<item>
<name>B</name>
<type>BBB</type>
</item>
<item>
<name>C</name>
<type>CCC</type>
</item>
</itemList>
</root>
XML;
$xml = new SimpleXMLElement($xmlStr);
$res = $xml->xpath('//type[contains(text(), "BBB")]/parent::*/preceding-sibling::*');
echo "{$res[0]->name} ({$res[0]->type})";