【问题标题】:PHP DOM Parser Moving Closing Div TagPHP DOM 解析器移动关闭 div 标记
【发布时间】:2018-02-14 21:51:32
【问题描述】:

这是我的代码:

$myHtml = '
<div class="div-class">
    <p>text</p>

    <p><a href="#">text</a></p>
</div>

<ul class="some-class">
    <li><a href="#" target="_blank" title="something something"><img src="" alt=""></a>
    </li>
    <li><a href="" target="_blank" title=""><img src="" alt=""></a>
    </li>
    <li><a href="" target="_blank" title=""><img src=""></a>
    </li>
</ul>
';

$doc = new \DOMDocument();
$doc->loadHTML($myHtml, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xpath = new \DOMXPath($doc);
$anchors = $xpath->query("//a[@title='something something']");
$list = $xpath->query("//ul[@class='some-class']")[0];
foreach ($anchors as $a) {
    $list->removeChild($a->parentNode);
}

var_dump($doc->saveHTML());

本质上,我正在尝试删除包含标题为“某事某事”的锚标记的列表项。但是,当我在应用更改后保存 html 时,列表会移动到 div 标记内。为什么会出现这种情况?谢谢。

【问题讨论】:

    标签: php html string domparser


    【解决方案1】:

    loadHTML() 尝试更正语法,它不喜欢 ul 元素是无父元素,因此它将其移动到 div 内。如果将其全部包裹在 body 标记周围,它将正常工作。

    <?php
    $myHtml = '
    <html>
    <body>
    <div class="div-class">
        <p>text</p>
    
        <p><a href="#">text</a></p>
    </div>
    
    <ul class="some-class">
        <li><a href="#" target="_blank" title="something something"><img src="" alt=""></a>
        </li>
        <li><a href="" target="_blank" title=""><img src="" alt=""></a>
        </li>
        <li><a href="" target="_blank" title=""><img src=""></a>
        </li>
    </ul>
    </body>
    </html>
    ';
    
    $doc = new \DOMDocument();
    $doc->loadHTML($myHtml, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
    $xpath = new \DOMXPath($doc);
    $anchors = $xpath->query("//a[@title='something something']");
    $list = $xpath->query("//ul[@class='some-class']")[0];
    foreach ($anchors as $a) {
        $list->removeChild($a->parentNode);
    }
    
    var_dump($doc->saveHTML());
    

    Demo

    或者,没有LIBXML_HTML_NOIMPLIED 标志:

    <?php
    $myHtml = '
    <div class="div-class">
        <p>text</p>
    
        <p><a href="#">text</a></p>
    </div>
    
    <ul class="some-class">
        <li><a href="#" target="_blank" title="something something"><img src="" alt=""></a>
        </li>
        <li><a href="" target="_blank" title=""><img src="" alt=""></a>
        </li>
        <li><a href="" target="_blank" title=""><img src=""></a>
        </li>
    </ul>
    ';
    
    $doc = new \DOMDocument();
    $doc->loadHTML($myHtml, LIBXML_HTML_NODEFDTD);
    var_dump (libxml_get_errors());
    $xpath = new \DOMXPath($doc);
    $anchors = $xpath->query("//a[@title='something something']");
    $list = $xpath->query("//ul[@class='some-class']")[0];
    foreach ($anchors as $a) {
        $list->removeChild($a->parentNode);
    }
    
    var_dump($doc->saveHTML());
    

    Demo

    【讨论】:

    • 感谢@ishegg 的回复。除了添加/剥离body标签还有其他方法吗?
    • 您看到编辑后的答案了吗?如果您删除LIBXML_HTML_NOIMPLIED,它将工作而无需更改任何其他内容。
    • 但是如果你删除 LIBXML_HTML_NOIMPLIED,它会添加 body 和 html 标签打开/关闭标签。
    • 我明白你的意思。 AFAIK,不,DOMDocument 将始终尝试“修复”您的标记。也许作为一种解决方法,将所有内容包装在一个假标签中然后将其删除?
    • 谢谢。我最终只使用了虚拟 div 并将它们留在那里。
    猜你喜欢
    • 2010-10-25
    • 1970-01-01
    • 1970-01-01
    • 2012-02-28
    • 1970-01-01
    • 1970-01-01
    • 2011-07-25
    • 2010-09-22
    • 2012-08-12
    相关资源
    最近更新 更多