如何将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> this is a really html string ©</div><i></i> with all the © 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**);