我使用这个XPath查询选择没有输入后代XHTML文档中的元素:如何仅选择此XPath查询中的“顶级节点”?
//*[not(descendant-or-self::input | descendant-or-self::textarea | descendant-or-self::select | ancestor::select)]
用下面的例子XHTML文档:
<html>
<head>
<title>Title</title>
</head>
<body>
<div id="one">
<input type="text" />
</div>
<div id="two">
<textarea></textarea>
</div>
<div id="three">
<div id="four">
Text
</div>
</div>
<div id="five">
<select>
<option>One</option>
<option>Two</option>
</select>
</div>
<div id="six">
<input type="text" />
</div>
<div id="seven">
<div id="eight"></div>
</div>
</body>
</html>
...这PHP代码:
// Populate $html and $query with above
$dom = new DOMDocument('1.0', 'UTF-8');
$dom->loadXML($html);
$xpath = new DOMXPath($dom);
$nodes = $xpath->query($query);
foreach($nodes as $node)
{
echo $node->tagName;
if($node->hasAttribute('id'))
echo '#' . $node->getAttribute('id');
echo ' ';
}
我得到这个:head title div#three div#four div#seven div#eight
但我想要这个:head div#three div#seven
我将采取XPath查询的结果并从DOMDocument中删除元素。 title div#four div#eight
是head div#three div#seven
的子项,它们已经在结果中。
记住这个查询将用于任何XHtml文档,我将如何更改我的XPath 1.0查询以获得所需的结果?
这个工程!似乎只要重复的条件是'和(../descendant::put | ../descendant::textarea | ../ descendant :: select)'就足够了。第一个条件中的“祖先或自我选择”部分确保了“select”的内部是独立的。如果我理解正确,'../'部分选择“根父”,这正是我想要的,谢谢:)。如果没有字段元素,我还添加了一个回退选择根节点'html'。 – Luke 2012-02-14 17:48:10
当'html'元素出现'xmlns'属性时,我发现查询不起作用。因为什么原因,你不能简单地执行'$ xpath-> registerNamespace(NULL,'http://www.w3.org/1999/xhtml')'...因此,你必须将'NULL'改为' 'html',当xmlns存在时,执行'$ query = str_replace('::',':: input:',$ query)'。你可以使用'$ xmlns = $ document-> lookupNamespaceURI(NULL)'来查看它是否存在。希望有更好的方法。如果有,请告诉我! – Luke 2012-02-14 19:11:42