如何将HTML插入到PHP DOMNode?

有什么办法可以插入一个HTML模板到现有的DOMNode没有内容被编码?

我试图做到这一点:

$dom->createElement('div', '<h1>Hello world</h1>'); $dom->createTextNode('<h1>Hello world</h1>'); 

输出几乎是相同的,唯一不同的是,第一个代码将它包装在一个div。 我曾尝试从string加载HTML,但我不知道如何将其正文内容附加到另一个DOMDocument。

在JavaScript中,这个过程似乎很简单明了。

它与另一个DOMDocument一起用于parsingHTML代码。 但是您需要将节点导入主文档,然后才能在其中使用它们:

 $newDiv = $dom->createElement('div'); $tmpDoc = new DOMDocument(); $tmpDoc->loadHTML($str); foreach ($tmpDoc->getElementsByTagName('body')->item(0)->childNodes as $node) { $node = $dom->importNode($node, true); $newDiv->appendChild($node); } 

作为一个方便的function:

 function appendHTML(DOMNode $parent, $source) { $tmpDoc = new DOMDocument(); $tmpDoc->loadHTML($source); foreach ($tmpDoc->getElementsByTagName('body')->item(0)->childNodes as $node) { $node = $parent->ownerDocument->importNode($node, true); $parent->appendChild($node); } } 

那么你可以简单地做到这一点:

 $elem = $dom->createElement('div'); appendHTML($elem, '<h1>Hello world</h1>'); 

您可以使用

  • DOMDocumentFragment::appendXML – 追加原始XML数据

例:

 // just some setup $dom = new DOMDocument; $dom->loadXml('<html><body/></html>'); $body = $dom->documentElement->firstChild; // this is the part you are looking for $template = $dom->createDocumentFragment(); $template->appendXML('<h1>This is <em>my</em> template</h1>'); $body->appendChild($template); // output echo $dom->saveXml(); 

输出:

 <?xml version="1.0"?> <html><body><h1>This is <em>my</em> template</h1></body></html> 

如果要从另一个DOMDocument导入,请用三个行replace

 $tpl = new DOMDocument; $tpl->loadXml('<h1>This is <em>my</em> template</h1>'); $body->appendChild($dom->importNode($tpl->documentElement, TRUE)); 

使用TRUE作为importNode的第二个参数将执行节点树的recursion导入。


如果您需要导入(格式错误的)HTML, loadXml loadHTML更改为loadHTML 。 这将触发libxml的HTMLparsing器(内部使用什么ext / DOM):

 libxml_use_internal_errors(true); $tpl = new DOMDocument; $tpl->loadHtml('<h1>This is <em>malformed</em> template</h2>'); $body->appendChild($dom->importNode($tpl->documentElement, TRUE)); libxml_use_internal_errors(false); 

请注意,libxml将尝试更正标记,例如它会将错误的closures</h2>更改为</h1>

因为我不想与XML争斗,因为它会更快地抛出错误,而且我不是为了防止错误输出而加上@的前缀。 loadHTML在我看来做得比较好,这很简单:

 $doc = new DOMDocument(); $div = $doc->createElement('div'); // use a helper to load the HTML into a string $helper = new DOMDocument(); $helper->loadHTML('<a href="#">This is my HTML Link.</a>'); // now the magic! // import the document node of the $helper object deeply (true) // into the $div and append as child. $div->appendChild($doc->importNode($helper->documentElement, true)); // add the div to the $doc $doc->appendChild($div); // final output echo $doc->saveHTML(); 

下面是使用DOMDocumentFragment的简单示例:

 $doc = new DOMDocument(); $doc->loadXML("<root/>"); $f = $doc->createDocumentFragment(); $f->appendXML("<foo>text</foo><bar>text2</bar>"); $doc->documentElement->appendChild($f); echo $doc->saveXML(); 

这里是replaceDOMNode的帮助函数:

 /** * Helper function for replacing $node (DOMNode) * with an XML code (string) * * @var DOMNode $node * @var string $xml */ public function replaceNodeXML(&$node, $xml) { $f = $this->dom->createDocumentFragment(); $f->appendXML($xml); $node->parentNode->replaceChild($f,$node); } 

来源:一些旧的“基于PHP5 Dom的模板”文章。

这里是Pian0_M4n发布的另一个build议,使用value属性作为解决方法:

 $dom = new DomDocument; // main object $object = $dom->createElement('div'); // html attribute $attr = $dom->createAttribute('value'); // ugly html string $attr->value = "<div>&nbsp; this is a really html string &copy;</div><i></i> with all the &copy; that XML hates!"; $object->appendChild($attr); // jquery fix (or javascript as well) $('div').html($(this).attr('value')); // and it works! $('div').removeAttr('value'); // to clean-up 

没有理想,但至less是有效的。

Gumbo的代码完美的工作! 只是添加TRUE参数,以便它与嵌套的HTML片段一起工作的一点点改进。

 $node = $parent->ownerDocument->importNode($node); $node = $parent->ownerDocument->importNode($node, **TRUE**);