如何将HTML片段组合到DOMDocument中?

时间:2011-01-18 17:18:43

标签: php html parsing dom

对于代表HTML文档各部分的文件,loadHTMLloadHTMLFile似乎为每个部分填写htmlbody标记,正如我所揭示的那样输出如下:

$doc = new DOMDocument();
$doc->loadHTMLFile($file);
$elements = $doc->getElementsByTagName('*');

if( !is_null($elements) ) {
    foreach( $elements as $element ) {
        echo "<br/>". $element->nodeName. ": ";

        $nodes = $element->childNodes;
        foreach( $nodes as $node ) {
            echo $node->nodeValue. "\n";
        }
    }
}

由于我计划在我自己的代码中将这些部分组装到更大的文档中,并且我已被指示使用DOMDocument来执行此操作,我该怎么做才能防止此行为?

2 个答案:

答案 0 :(得分:1)

这是HTML parser module of libxml对文档进行的若干修改的一部分,以便使用损坏的HTML。只有在部分标记上使用loadHTMLloadHTMLFile时才会出现此问题。如果您知道部分有效X(HT)ML,请改用loadloadXML

您可以使用

$doc->saveXml($doc->getElementsByTagName('body')->item(0));

转储body元素的outerHTML,例如<body>anything else</body>并使用str_replace删除body元素,或使用substr提取内部html。

$html = '<p>I am a fragment</p>';
$dom = new DOMDocument;
$dom->loadHTML($html); // added html and body tags
echo substr(
    $dom->saveXml(
        $dom->getElementsByTagName('body')->item(0)
    ),
    6, -7
);
// <p>I am a fragment</p>

请注意,这将使用符合XHTML标记,因此<br>将成为<br/>。从PHP 5.3.5开始,无法将节点传递给saveHTML()A bug request has been filed.

答案 1 :(得分:0)

您最接近的是使用DOMDocumentFragment

然后你可以这样做:

$doc = new DOMDocument();
...
$f = $doc->createDocumentFragment();
$f->appendXML("<foo>text</foo><bar>text2</bar>"); 
$someElement->appendChild($f);

但是,这需要XML,而不是HTML。

无论如何,我认为你正在创造一个人为的问题。由于您知道行为是创建htmlbody标记,因此您只需从body标记中提取文件中的元素,然后将其导入到您正在组装最终版本的DOMDocument中。文件。请参阅DOMDocument::importNode