How to insert HTML to PHP DOMNode?
You can use
Example:
// 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);// outputecho $dom->saveXml();
Output:
<?xml version="1.0"?><html><body><h1>This is <em>my</em> template</h1></body></html>
If you want to import from another DOMDocument, replace the three lines with
$tpl = new DOMDocument;$tpl->loadXml('<h1>This is <em>my</em> template</h1>');$body->appendChild($dom->importNode($tpl->documentElement, TRUE));
Using TRUE
as the second argument to importNode
will do a recursive import of the node tree.
If you need to import (malformed) HTML, change loadXml
to loadHTML
. This will trigger the HTML parser of libxml (what ext/DOM uses internally):
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);
Note that libxml will try to correct the markup, e.g. it will change the wrong closing </h2>
to </h1>
.
It works with another DOMDocument for parsing the HTML code. But you need to import the nodes into the main document before you can use them in it:
$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);}
And as a handy 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); }}
Then you can simply do this:
$elem = $dom->createElement('div');appendHTML($elem, '<h1>Hello world</h1>');
As I do not want to struggle with XML, because it throws errors faster and I am not a fan of prefixing an @ to prevent error output. The loadHTML does the better job in my opinion and it is quite simple as that:
$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 outputecho $doc->saveHTML();