修复HTML片段

时间:2010-12-30 09:25:08

标签: php html dom html-parsing

我正在尝试学习如何使用PHP's DOM functions。作为练习,我想修复无效的HTML 片段。到目前为止,我已经能够生成完整文档

<?php

$fragment = '<div style="font-weight: bold">Lorem ipsum <div>dolor sit amet,
    <strong><em class=foo>luptate</strong></em>. Excepteur proident,
    <div class="bar">sunt in culpa</div> officia est laborum.';

$doc = new DOMDocument;
libxml_use_internal_errors(TRUE);
$doc->loadHTML($fragment);
libxml_use_internal_errors(FALSE);
$doc->formatOutput = TRUE;
echo $doc->saveHTML();

?>

...打印:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><div style="font-weight: bold">Lorem ipsum <div>dolor sit amet,
    <strong><em class="foo">luptate</em></strong>. Excepteur proident,
    <div class="bar">sunt in culpa</div> officia est laborum.</div>
</div></body></html>

我的问题:

  1. 有没有办法只打印与原始片段对应的HTML?
  2. 是否有更适合此类任务的内置库?

4 个答案:

答案 0 :(得分:1)

这应该有用,但有点难看

$doc->loadHTML($fragment);
echo simplexml_import_dom( $doc->getElementsByTagName('div')->item(0) )->asXML();

<强>输出:

<div style="font-weight: bold">Lorem ipsum <div>dolor sit amet,
  <strong><em class="foo">luptate</em></strong>. Excepteur proident,
    <div class="bar">sunt in culpa</div> officia est laborum.</div></div>

稍微优雅

$xpath   = new DOMXPath($doc);
$query   = '/html/body/*';        <-- always <html><body>...
$entries = $xpath->query($query);
foreach ($entries as $entry)
{
  echo simplexml_import_dom($entry)->asxml();
}

答案 1 :(得分:1)

似乎最新的PHP版本最终实现了这个:

How to return outer html of DOMDocument?

我们可以这样做:

if( version_compare(PHP_VERSION, '5.3.6', '>=') ){
    $body = $dom->documentElement->firstChild;
    if( $body->hasChildNodes() ){
        foreach($body->childNodes as $node){
            echo $dom->saveHTML($node);
        }
    }
}

......或者这个:

if( version_compare(PHP_VERSION, '5.3.6', '>=') ){
    $body = $dom->getElementsByTagName('body')->item(0);
    if( $body->hasChildNodes() ){
        foreach($body->childNodes as $node){
            echo $dom->saveHTML($node);
        }
    }
}

太糟糕了,我们仍然需要为旧版本提供一个丑陋的解决方法。

答案 2 :(得分:0)

您可以运行一个功能来替换您不想要的部分,例如:

$result = $doc->saveHTML();
$result = str_replace('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"><html><body>', '', $result);
$result = str_replace('</body></html>', '', $result);

你总是可以尝试这个课程:

http://www.barattalo.it/html-fixer/

这显然会像这样容易:

$dirty_html = ".....bad html here......";

$a = new HtmlFixer();
$clean_html = $a->getFixedHtml($dirty_html);

这一切都取决于你将如何处理这些信息。

答案 3 :(得分:0)

好吧,PHP&gt; = 5.1显然也有一个DocumentFragment,它有一个appendXML函数:http://php.net/manual/en/domdocumentfragment.appendxml.php。也许你可以使用它?我不确定它是否有自己的字符串表示,但谁知道。

编辑:

嗯,这不起作用:)。

但是,您可以直接使用SimpleXML,或者通过创建DOMElement然后使用simplexml_import_dom($domelement)->asXML()http://php.net/manual/en/function.simplexml-import-dom.php来使用SimpleXML。祝好运! :)