如何仅选择此XPath查询中的“顶级节点”?

时间:2012-02-14 07:15:28

标签: php xpath domxpath

我正在使用此XPath查询来选择Xhtml文档中没有输入后代的元素:

//*[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#eighthead div#three div#seven的子项,已在结果中。

请记住,此查询将用于任何XHtml文档,如何更改我的XPath 1.0查询以获得所需的结果?

2 个答案:

答案 0 :(得分:1)

只需重复父母的条件:

[not(descendant-or-self::input | descendant-or-self::textarea | descendant-or-self::select | ancestor-or-self::select)
and 
(../descendant-or-self::input | ../descendant-or-self::textarea | ../descendant-or-self::select | ../ancestor-or-self::select)]

答案 1 :(得分:0)

在这种情况下,似乎足以扩展当前的xpath,另外说div轴中不应该有headancestor

//*[not(descendant-or-self::input 
      | descendant-or-self::textarea 
      | descendant-or-self::select 
      | ancestor::select
      | ancestor::div
      | ancestor::head)]

在示例xml上,根据需要,它只返回headdiv s threeseven

相关问题