PHP 使用 DOMDocument 或 SimpleXML 的 xpath 结果的 xpath

PHP xpath on the result of an xpath with either DOMDocument or SimpleXML

我正在尝试对先前 xpath 查询的结果执行 xpath 查询。我可以编写 xpath 查询来提取子元素,然后迭代生成的元素,将它们传递给另一个函数以进行进一步处理。当我想为每个结果元素应用另一个 xpath 时,我的问题就来了。

鉴于 XML

<grandfather>
    <mother>
       <son>1</son>
       <son>2</son>
    </mother>
    <mother>
       <daughter>3</daughter>
    </mother>
    <mother>
       <daughter>4</daughter>
       <son>5</son>
    </mother>
<grandfather>

我可以用 xpath /grandfather/mother 获取所有的母亲节点,但是我可以在一个单独的函数中查询那些母亲节点,使用传递的母亲节点作为下一个查询的相对根节点吗?

当 XML 有一个名称空间时,您需要注册该名称空间才能让 xpath 工作,问题会变得复杂。使用SimpleXML,在第一次xpath查询之前注册的命名空间前缀不会保留在查询结果中,所以需要重新注册才能进行后续查询。

DOMXpath::evaluate() 的第二个参数是表达式的上下文。这是一个在您的 xml:

上工作的小例子
$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);

foreach ($xpath->evaluate('//mother') as $mother) {
  var_dump(
    $xpath->evaluate('count(daughter)', $mother),
    $xpath->evaluate('count(son)', $mother)
  );
}

您必须将 Xpath 实例提供到函数中以保持命名空间注册。

可以扩展 DOMDocument 和另一个 DOMNode 类 以允许在对象级别注册。我在 FluentDOM 中实现了它。

您可以通过在查询字符串的开头使用 ./ 并使用第一个结果节点作为第二个参数:

$motherList=$xml->query('/grandfather/mother');
$aMother=$motherList[0];
$daughterList=$xml->query('./daugther',$aMother);