嵌套DOM XPath?

时间:2013-06-06 00:02:25

标签: php domdocument

假设您有类似

的内容
<div>
    <p>...</p>
    <p>There are an unbounded number of these p tags</p>
    <p>etc etc...could be 4 of these one time, then 9 the next time</p>
</div>
<div>
    <p>Same here, an unbounded number</p>
    <p>etc</p>
</div>
<div>
    <p>And so on...</p>
    <p>...</p>
    <p>...</p>
    <p>...</p>
</div>

假设我想从第一个div中取出第一个p节点,从第二个div中取出第二个p节点,从第三个div中取出第三个p节点。现在如果这是xml,我会使用SimpleXMLElement并执行类似

的操作
foreach ($data->xpath('//div') as $cur){
      //Then work within each <div> that is returned, could even xpath this again if I needed to
    }

但是如何在DOM XPath中单独选择每个div然后在每个div中工作,还是做等效的?如果我说的话

$query = $data->query('//div');

我会得到一个DOMElements列表,据我所知,它不能在另一个DOM XPath中使用(现在如果它可能会起作用我想),所以我无法嵌套XPath请求或者至少我是当我尝试使用nodeValue / textValue并使用它创建一个新的DOMDocument和DOMXPath时,没有得到任何结果。 nodeValue / textValue似乎剥离了所有标签,这就是为什么我认为它没有返回任何结果。

现在我可以在这种情况下用'\ n'分隔并解析nodeValue,但想象在每个div中每个类型的子节点都有无限数量,我们正在寻找一些事情,比如5级。然后那就变成了一个巨大的丑陋混乱。

基本上,SimpleXMLElement-&gt; xpath保留了文档结构,而DOM XPath似乎没有。

那么,有一个很好的一般方法吗?

1 个答案:

答案 0 :(得分:7)

您可以访问嵌套元素。例如,如果要访问第二个div的第一段中的文本,可以按以下方式执行:

$doc = new DOMDocument();
if ( ! @$doc->loadHTML($html)){
    return FALSE;
}
$xpath = new DOMXPath($doc);
$res = $xpath->query('//div');
$sub = $xpath->query('.//p', $res->item(1));//paragraphs of second div 
echo trim($sub->item(0)->nodeValue);//first paragraph

请注意,$sub是相对于$res中存储的第一个查询的查询。

输出结果为:

同样在这里,是一个无限数字