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);
我正在尝试对先前 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);