比$ DOMDocument-> getNodePath();

时间:2015-11-03 14:59:26

标签: php xml xpath nodes domdocument

我目前需要一个元素的XPath路径。路径必须包含唯一标识路径中每个元素的属性(在本例中为name属性)。

$DOMDocument->getNodePath();返回路径,但没有属性。这些属性是必要的,因为XML会发生很大的变化。

我目前正在编写一种方法来手动浏览并检查路径中每个元素的name属性,然后将其插入到适当位置的字符串中。这样做是否更容易/更快/更不像黑客一样?

2 个答案:

答案 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表达式,它从上下文节点开始提取所有元素节点,直到文档元素。