如何将 HTML 插入 PHP DOMNode?

2022-08-30 12:49:22

有没有办法在不编码内容的情况下将HTML模板插入到现有的DOMNode中?

我试图用以下方式做到这一点:

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

输出几乎相同,唯一的区别是第一个代码会将其包装在div中。我试图从字符串加载HTML,但我不知道如何将它的正文内容附加到另一个DOMDocument。

在javascript中,这个过程似乎非常简单明了。


答案 1

您可以使用

例:

// 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 导入,请将这三行替换为

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

用作 importNode 的第二个参数将执行节点树的递归导入。TRUE


如果需要导入(格式不正确的)HTML,请更改为 。这将触发 libxml 的 HTML 解析器(ext/DOM 内部使用):loadXmlloadHTML

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 将尝试更正标记,例如,它会将错误的关闭更改为 。</h2></h1>


答案 2

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

$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 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>');

推荐