带有DOMDocument或SimpleXML

时间:2016-04-25 19:23:20

标签: php xml xpath simplexml domdocument

我正在尝试对早期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查询之前注册的名称空间前缀不会保留在查询结果中,因此您必须再次注册它以用于后续查询。

2 个答案:

答案 0 :(得分:1)

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中实现了它。

答案 1 :(得分:0)

您可以在查询字符串的开头使用./并使用第一个结果节点作为第一个结果节点的原始xpathDocument, relative 进行第二次查询第二个参数:

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