对于代表HTML文档各部分的文件,loadHTML
和loadHTMLFile
似乎为每个部分填写html
和body
标记,正如我所揭示的那样输出如下:
$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来执行此操作,我该怎么做才能防止此行为?
答案 0 :(得分:1)
这是HTML parser module of libxml对文档进行的若干修改的一部分,以便使用损坏的HTML。只有在部分标记上使用loadHTML
和loadHTMLFile
时才会出现此问题。如果您知道部分有效X(HT)ML,请改用load
和loadXML
。
您可以使用
$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。
无论如何,我认为你正在创造一个人为的问题。由于您知道行为是创建html
和body
标记,因此您只需从body标记中提取文件中的元素,然后将其导入到您正在组装最终版本的DOMDocument中。文件。请参阅DOMDocument::importNode
。