XPath直到下一个标签

时间:2015-11-27 14:18:17

标签: php xpath domdocument

类似于其他人在此问过的问题,但由于我无法弄清楚如何应用这些建议,我需要一些帮助。

我想找到一个html文档的节点,它有一个像这样的结构(提取,可以变化):

<h2>My title 1</h2>
<h3>Sub-heading</h3>
<p>...<span><a href='#'>...</a></span></p>
<div>...</div>
<h2>My title 2</h2>
<p>No sub-heading here :O</p>
<h3>But here</h3>
<p>No link</p>
<h2>And so on...</h2>
<p>...</p>

我想要完成的是找到从一个h2到下一个h2之前的最后一个项目的所有节点,包括h2本身。在我的例子中,我想要像这样修改“块”:

第1区:

<h2>My title 1</h2>
<h3>Sub-heading</h3>
<p>...<span><a href='#'>...</a></span></p>
<div>...</div>

第2座:

<h2>My title 2</h2>
<p>No sub-heading here :O</p>
<h3>But here</h3>
<p>No link</p>

第3区:

<h2>And so on...</h2>
<p>...</p>

除了h2之外,我没有更多的目标(没有id,没有文字内容我可以知道,没有肯定的内容等)。

1 个答案:

答案 0 :(得分:1)

您可以使用DOMXpathquery方法。

首先找到身体中的所有h2元素(不是嵌套的h2元素)

然后为找到的每个h2启动foreach循环。 然后将h2添加到数组$set,因为您要保存它。 然后循环兄弟姐妹并将其添加到数组$set直到您找到的下一个h2。

$set添加到$sets数组。

例如:

$html = <<<HTML
<h2>My title 1</h2>
<h3>Sub-heading</h3>
<p>...<span><a href='#'>...</a></span></p>
<div>...</div>
<h2>My title 2</h2>
<p>No sub-heading here :O</p>
<h3>But here</h3>
<p>No link</p>
<h2>And so on...</h2>
<p>...</p>
<div><h2>This is nested</h2></div>
HTML;

$doc = new DOMDocument();
$doc->loadHTML($html);
$xpath = new DOMXpath($doc);
$domNodeList = $xpath->query('/html/body/h2');

$sets = array();

foreach($domNodeList as $element) {
    // Save the h2
    $set = array($element);

    // Loop the siblings unit the next h2
    while ($element = $element->nextSibling) {
        if ($element->nodeName === "h2") {
            break;
        }
        // if Node is a DOMElement
        if ($element->nodeType === 1) {
            $set[] = $element;
        }
    }

    $sets[] = $set;
}

$ sets现在将包含3个数组,其中包含您添加的DOMElements。

Demo with var_dump of $sets