parser - php string to dom




如何将HTML插入PHP DOMNode? (4)

有没有什么方法可以在没有内容编码的情况下将HTML模板插入现有DOMNode?

我试过这样做:

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

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

在javascript中,这个过程看起来非常简单明了。


Gumbo的代码完美无缺! 只是一点点增强,添加TRUE参数,使其适用于嵌套的html片段。

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

您可以使用

例:

// 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));

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

如果您需要导入(格式错误的)HTML, loadXml loadHTML更改为loadHTML 。 这将触发libxml的HTML解析器(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将尝试更正标记,例如,它会将错误的结束</h2>更改为</h1>


它与另一个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>');

这是使用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();

这是替换DOMNode的辅助函数:

/** 
 * 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 Based Template”文章。

这是Pian0_M4n发布的Pian0_M4n使用属性作为解决方法的建议:

$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

不理想,但至少它有效。





domdocument