Php 将H3标签和所有UL标签包装在一个div中

Php 将H3标签和所有UL标签包装在一个div中,php,domdocument,Php,Domdocument,我有一个这样的结构: <h3><span class="header" id="first_set">My Heading</span></h3> <ul><li>Text Text Text</li></ul> <ul><li>Text Text Text</li></ul> <ul><li>Text Text Text<

我有一个这样的结构:

<h3><span class="header" id="first_set">My Heading</span></h3>
<ul><li>Text Text Text</li></ul>
<ul><li>Text Text Text</li></ul>
<ul><li>Text Text Text</li></ul>
<h3><span class="header" id="second_set">My Second Heading</span></h3>
<ul><li>Text Text Text</li></ul>
<ul><li>Text Text Text</li></ul>
<ul><li>Text Text Text</li></ul>
<h3><span class="header" id="third_set">My Third Heading</span></h3>
<ul><li>Text Text Text</li></ul>
<ul><li>Text Text Text</li></ul>
<ul><li>Text Text Text</li></ul>
<h3><span class="header" id="first_set">My Heading</span></h3>
<ul><li>Text Text Text</li></ul>
<ul><li>Text Text Text</li></ul>
<ul><li>Text Text Text</li></ul>
<div class="second_heading">
<h3><span class="header" id="second_set">My Second Heading</span></h3>
<ul><li>Text Text Text</li></ul>
<ul><li>Text Text Text</li></ul>
<ul><li>Text Text Text</li></ul>
</div>
<h3><span class="header" id="third_set">My Third Heading</span></h3>
<ul><li>Text Text Text</li></ul>
<ul><li>Text Text Text</li></ul>
<ul><li>Text Text Text</li></ul>
我使用DOMDocument从一个网页中提取了这个。我需要遍历9000页,这些页面都有细微的变化。因此,在某些情况下,第三个标题实际上可能是一个表,而不是另一个h3

我试图准确地做的是在第二个标题周围环绕一个div,当它没有找到更多标签时关闭div,直到它碰到任何不是ul标签的东西。结果是这样的:

<h3><span class="header" id="first_set">My Heading</span></h3>
<ul><li>Text Text Text</li></ul>
<ul><li>Text Text Text</li></ul>
<ul><li>Text Text Text</li></ul>
<h3><span class="header" id="second_set">My Second Heading</span></h3>
<ul><li>Text Text Text</li></ul>
<ul><li>Text Text Text</li></ul>
<ul><li>Text Text Text</li></ul>
<h3><span class="header" id="third_set">My Third Heading</span></h3>
<ul><li>Text Text Text</li></ul>
<ul><li>Text Text Text</li></ul>
<ul><li>Text Text Text</li></ul>
<h3><span class="header" id="first_set">My Heading</span></h3>
<ul><li>Text Text Text</li></ul>
<ul><li>Text Text Text</li></ul>
<ul><li>Text Text Text</li></ul>
<div class="second_heading">
<h3><span class="header" id="second_set">My Second Heading</span></h3>
<ul><li>Text Text Text</li></ul>
<ul><li>Text Text Text</li></ul>
<ul><li>Text Text Text</li></ul>
</div>
<h3><span class="header" id="third_set">My Third Heading</span></h3>
<ul><li>Text Text Text</li></ul>
<ul><li>Text Text Text</li></ul>
<ul><li>Text Text Text</li></ul>

我正在考虑preg_replace,但不确定在找到最后一个关闭ul标记时如何执行关闭div的逻辑。

您可以在使用DOMDocument的同时实现这一点。我假设您有一个名为$node的变量,它是您在问题中显示的HTML上方的节点。在这种情况下,您可以使用DOMXPath找到该元素的所有子节点,然后对它们进行迭代,直到找到第二个节点,并将该节点和所有后续元素附加到一个新节点,直到找到第二个标头之后的第一个非元素:

$div = $doc->createElement('div');
$xpath = new DOMXPath($doc);
$headers = 0;
foreach ($xpath->query('./*', $node) as $child) {
    echo $child->nodeName;
    switch ($child->nodeName) {
        case 'h3':
            $headers++;
            if ($headers == 2) {
                $node->replaceChild($div, $child);
                $div->appendChild($child);
            }
            else if ($headers == 3) {
                break 2;
            }
            break;
        case 'ul':
            if ($headers == 2) $div->appendChild($child);
            break;
        default:
            // if a non-ul element after the 2nd header, exit the loop
            if ($headers == 2) break 2;
            break;
    }
}

杰出的非常感谢。我把它从DomDocument中拿出来,然后试图操纵它,使它变得过于复杂。