PHP Xpath - 解析平面HTML结构

时间:2011-11-06 22:49:21

标签: php html xpath

我正在尝试解析一些相当平坦的HTML并将所有内容从一个h1标签分组到下一个标签。例如,我有以下HTML:

<h1> Heading 1 </h1>
<p> Paragraph 1.1 </p>
<p> Paragraph 1.2 </p>
<p> Paragraph 1.3 </p>
<h1> Heading 2 </h1>
<p> Paragraph 2.1 </p>
<p> Paragraph 2.2 </p>
<h1> Heading 3 </h1>
<p> Paragraph 3.1 </p>
<p> Paragraph 3.2 </p>
<p> Paragraph 3.3 </p>

我基本上希望它看起来像:

<div id='1'>
    <h1> Heading 1 </h1>
    <p> Paragraph 1.1 </p>
    <p> Paragraph 1.2 </p>
    <p> Paragraph 1.3 </p>
</div>
<div id='2'>
    <h1> Heading 2 </h1>
    <p> Paragraph 2.1 </p>
    <p> Paragraph 2.2 </p>
</div>
<div id='3'>
    <h1> Heading 3 </h1>
    <p> Paragraph 3.1 </p>
    <p> Paragraph 3.2 </p>
    <p> Paragraph 3.3 </p>
</div>

到目前为止,发布我已经完成的代码可能还不值得,因为它变成了一团糟。基本上我试图为'// h1'做一个Xpath查询。创建新的DIV标记作为父节点。然后将h1 DOM节点复制到第一个DIV中,然后遍历nextSibling,直到我点击另一个h1标签 - 如上所述,它变得很乱。

有人能指出我在这方面有更好的方向吗?

1 个答案:

答案 0 :(得分:3)

迭代同一级别的所有节点(我在示例中创建了一个名为platau的提示节点),每当你在<h1>之间运行时,先插入div并保留对它的引用。

对于<h1>和任何其他节点,如果引用存在,请删除该节点并将其作为子节点添加到引用中。

示例:

$doc->loadXML($xml);
$xp = new DOMXPath($doc);

$current = NULL;
$id = 0;
foreach($xp->query('/platau/node()') as $i => $sort)
{
    if (isset($sort->tagName) && $sort->tagName === 'h1')
    {
        $current = $doc->createElement('div');
        $current->setAttribute('id', ++$id);
        $current = $sort->parentNode->insertBefore($current, $sort);
    }
    if (!$current) continue;

    $sort->parentNode->removeChild($sort);
    $current->appendChild($sort);
}

Demo