PHP / DOMDocument等同于jQuery的wrapInner

时间:2013-11-30 13:08:49

标签: php domdocument

我有一堆HTML包含具有特定类的div(以及其他div)。我想要做的是将该div的内容包装在另一个div中。

此HTML:

<h1>Hello</h1>

<p>Lorem ipsum dolor</p>

<div class="section">
    <h2>Helllllooo</h2>

    <div class="left">Left</div>
    <div class="right">Right</div>
</div>

<p>Lorem ipsum dolor</p>

<div class="section">
    <h2>Bubye</h2>

    <div class="right">Right</div>
    <div class="left">Left</div>
</div>

完成后应该是这样的:

<h1>Hello</h1>

<p>Lorem ipsum dolor</p>

<div class="section"><div class="inner">
    <h2>Helllllooo</h2>

    <div class="left">Left</div>
    <div class="right">Right</div>
</div></div>

<p>Lorem ipsum dolor</p>

<div class="section"><div class="inner">
    <h2>Bubye</h2>

    <div class="right">Right</div>
    <div class="left">Left</div>
</div></div>

理想情况下,我喜欢jQuery的wrapInner; $('div.section').wrapInner('<div class="inner"></div>');

这就是我现在所拥有的(不起作用:P):

<?php
$doc = new DOMDocument();
$doc->loadHTML('<?xml encoding="utf-8" ?>' . $theContent); # XML Encoding trick to prevent bug (http://stackoverflow.com/questions/8218230/php-domdocument-loadhtml-not-encoding-utf-8-correctly?rq=1)
$divs = $doc->getElementsByTagName('div');

foreach ($divs as $div) {
    # Make sure we're on a div.section
    if (strpos($div->getAttribute('class'), 'section') != -1) {
        # Create wrapping div
        $inner = $doc->createElement('div');
        $inner->setAttribute('class', 'inner');

        # Move all children to new div
        while ($div->childNodes->length) {
            $inner->appendChild($div->childNodes->item(0));
        }

        # This doesn't work (item() is not a function)
    #   $div->appendChild($inner->item(0));

        # This freezes the page
    #   $div->appendChild($inner);

        # This looks perfect, all the elements from div.section inside a div.inner
        echo '<pre>' . htmlspecialchars($inner->ownerDocument->saveHTML($inner)) . '</pre>';
    }
}

# This looks as expected, a bunch of empty div.section elements
echo '<pre>' . htmlspecialchars($doc->saveHTML()) . '</pre>';

1 个答案:

答案 0 :(得分:1)

问题在于你正在修改你正在迭代的NodeList。

试试这个:

<?php
$doc = new DOMDocument();
$doc->loadHTML('<?xml encoding="utf-8" ?>' . $theContent); # XML Encoding trick to prevent bug (http://stackoverflow.com/questions/8218230/php-domdocument-loadhtml-not-encoding-utf-8-correctly?rq=1)
$divs = $doc->getElementsByTagName('div');
$section_div = array();

foreach ($divs as $div) {
    # Make sure we're on a div.section
    if (strpos($div->getAttribute('class'), 'section') !== FALSE) {
        $section_div[] = $div;
    }
}
foreach ($section_div as $div) {
    # Create wrapping div
    $inner = $doc->createElement('div');
    $inner->setAttribute('class', 'inner');

    # Move all children to new div
    while ($div->childNodes->length) {
        $inner->appendChild($div->childNodes->item(0));
    }

    # Append div.inner to div.section
    $div->appendChild($inner);
}

# This looks as expected, a bunch of empty div.section elements
echo '<pre>' . htmlspecialchars($doc->saveHTML()) . '</pre>';

注意:strpos如果找不到字符串,则返回FALSE