我目前需要一个元素的XPath路径。路径必须包含唯一标识路径中每个元素的属性(在本例中为name属性)。
$DOMDocument->getNodePath();
返回路径,但没有属性。这些属性是必要的,因为XML会发生很大的变化。
我目前正在编写一种方法来手动浏览并检查路径中每个元素的name属性,然后将其插入到适当位置的字符串中。这样做是否更容易/更快/更不像黑客一样?
答案 0 :(得分:1)
您可以使用XPath来获取字符串。例如,在xsh中:
for //address {
for ancestor-or-self::*
echo :s :n '/'
name()
xsh:if(@name, concat('[@name="', @name, '"]'),'') ;
echo ;
}
在以下XML
上运行它<root>
<customers name="2014">
<customer name="John">
<address/>
</customer>
<customer name="Jane">
<address/>
</customer>
</customers>
<customers name="2015">
<customer name="Daniel">
<address/>
</customer>
<customer name="Dave">
<address/>
</customer>
</customers>
</root>
我正在
/root/customers[@name="2014"]/customer[@name="John"]/address
/root/customers[@name="2014"]/customer[@name="Jane"]/address
/root/customers[@name="2015"]/customer[@name="Daniel"]/address
/root/customers[@name="2015"]/customer[@name="Dave"]/address
答案 1 :(得分:0)
@choroba的xsh解决方案可以使用DOMXpath::evaluate()
转换为PHP源:
$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);
foreach ($xpath->evaluate('//address') as $address) {
$path = '';
foreach ($xpath->evaluate('ancestor-or-self::*', $address) as $ancestor) {
$path .= '/'.$ancestor->nodeName;
if ($name = $ancestor->getAttribute('name')) {
$path .= '[@name = "'.$name.'"]';
}
}
var_dump($path);
}
ancestor-or-self::*
是一个Xpath表达式,它从上下文节点开始提取所有元素节点,直到文档元素。