Php 修复HTML片段

Php 修复HTML片段,php,html,dom,html-parsing,Php,Html,Dom,Html Parsing,我正在努力学习如何使用。作为练习,我想修复一个无效的HTML片段。到目前为止,我已经能够生成完整的文档: loadHTML($fragment); libxml\u使用\u内部错误(FALSE); $doc->formatOutput=TRUE; echo$doc->saveHTML(); ?> 。。。其中打印: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-

我正在努力学习如何使用。作为练习,我想修复一个无效的HTML片段。到目前为止,我已经能够生成完整的文档:

loadHTML($fragment);
libxml\u使用\u内部错误(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>

Lorem ipsum dolor sit amet,
羽状体。除了傲慢,
这是罪过。
我的问题是:

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

  • 您可以运行一个函数来替换不希望总是出现的部件,例如:

    $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);
    

    这完全取决于您将如何处理信息。

    好吧,PHP>=5.1显然还有一个
    DocumentFragment
    ,它有一个
    appendXML
    函数:。也许你可以用这个?我不确定它本身是否有字符串表示,但谁知道呢

    编辑:

    好吧,那不行:)


    但是,您可以直接使用SimpleXML,或者通过创建
    DomeElement
    然后使用
    SimpleXML\u导入dom($DomeElement)->asXML()
    :。祝你好运!:)

    这应该行得通,但有点难看

    $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>
    
    Lorem ipsum door sit amet,
    羽状体。除了傲慢,
    这是罪过。
    
    稍微优雅一点

    $xpath   = new DOMXPath($doc);
    $query   = '/html/body/*';        <-- always <html><body>...
    $entries = $xpath->query($query);
    foreach ($entries as $entry)
    {
      echo simplexml_import_dom($entry)->asxml();
    }
    
    $xpath=newdomxpath($doc);
    $query='/html/body/*';查询($query);
    foreach($entries作为$entry)
    {
    echo simplexml_import_dom($entry)->asxml();
    }
    
    最新的PHP版本似乎终于实现了这一点:

    这样我们就可以做到:

    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);
            }
        }
    }
    

    遗憾的是,对于旧版本,我们仍然需要一个难看的解决方案。

    使用字符串函数处理最终输出有点超过使用DOM的目的;-)谢谢你的链接,但正如我所说,这只是一个练习,所以我可以学习。是的,DocumentFragment看起来很有希望,但我也不能利用它。SimpleXML生成了一个完整的文档,我认为没有直接的机制(例如,
    DOMNode::outerHTML()
    方法),您必须自己编写。第一种方法假设一个特定的结构,但第二种方法工作得很好(尽管我正在将一些新行字符转换为HTML实体,这并不是完全错误,但很难看)
    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);
            }
        }
    }