这是我的基本结构:
<div id="PrimaryContentBlock">
<form>
......
我正在尝试从表单中选择元素,但XPath没有找到超过primarycontentblock div的任何内容。
第一个查询找到父节点,但第二个查询什么也找不到。
$dom->query('//*[@id="PrimaryContentBlock"]');
$dom->query('//*[@id="PrimaryContentBlock"]/form');
知道为什么XPath会表现得那么奇怪吗?在使用DOMXPath查询时,我一直看到很多不一致的行为。
答案 0 :(得分:1)
如果你有一个XHTML文档(在根xmlns
元素上有一个html
decalaration)并且你正在将它解析为XML,那么可能会发生这种情况。在这样的文档中,所有元素都是http://www.w3.org/1999/xhtml
命名空间的一部分,您需要在查询时指定它。
您的第一个查询//*[@id="PrimaryContentBlock"]
会找到任何带有id
属性的元素,包括XHTML命名空间中的那些(这就是*
的含义)。第二个查询//*[@id="PrimaryContentBlock"]/form
正在查找任何名称空间中不的form
个元素。由于所有form
元素都在默认的XHTML名称空间中,因此无法与文档匹配。
如果这是一个XHTML文档,最简单的解决方法是将其解析为HTML。如果您目前正在做类似的事情:
$domdocument->loadXML(...);
将其更改为使用loadHTML
:
$domdocument->loadHTML(...);
如果要将文档解析为XML,则需要在查询中指定命名空间。首先,您需要使用DOMXPath
实例register the namespace uri and prefix you are going to use,然后更改您的查询以包含新前缀:
$xpath = new DOMXPath($doc);
$xpath->registerNamespace('xhtml', "http://www.w3.org/1999/xhtml");
$result = $xpath->query('//*[@id="PrimaryContentBlock"]/xhtml:form')
答案 1 :(得分:0)
鉴于您拥有上述结构,并且您确信文档格式正确,您的查询将工作:
$xml = <<<EOF
<div id="PrimaryContentBlock">
<form></form>
</div>
EOF;
$doc = new DOMDocument();
$doc->loadHTML($xml);
$selector = new DOMXPath($doc);
foreach($selector->query('//*[@id="PrimaryContentBlock"]/form') as $element) {
echo $element->nodeName;
}
输出:
form
如果以下句子适合您:
在使用DOMXPath查询时,我一直看到很多不一致的行为。
...那么你对XPath的专业知识不够,或者你的输入数据不是很好。当我遇到某个查询问题时,至少有一个原因适用于我。