domnode - nodevalue php
¿Cómo insertar HTML a PHP DOMNode? (5)
¡El código de Gumbo funciona a la perfección! Solo una pequeña mejora que agrega el parámetro TRUE para que funcione con fragmentos html anidados.
$node = $parent->ownerDocument->importNode($node);
$node = $parent->ownerDocument->importNode($node, **TRUE**);
¿Hay alguna forma de que pueda insertar una plantilla HTML en un DOMNode existente sin contenido codificado?
He intentado hacer eso con:
$dom->createElement(''div'', ''<h1>Hello world</h1>'');
$dom->createTextNode(''<h1>Hello world</h1>'');
El resultado es prácticamente el mismo, con la única diferencia de que el primer código lo envolvería en un div. He intentado cargar HTML desde la cadena, pero no tengo idea de cómo puedo agregar su contenido corporal a otro DOMDocument.
En javascript, este proceso parece ser bastante simple y obvio.
Aquí hay un ejemplo simple al usar 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();
Aquí está la función auxiliar para reemplazar 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);
}
Fuente: Algún viejo artículo "PHP5 Dom Based Template".
Y aquí hay otra sugerencia publicada por Pian0_M4n para usar el atributo de valor como solución Pian0_M4n :
$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
No es ideal, pero al menos funciona.
Como no quiero luchar con XML, porque arroja errores más rápido y no soy partidario de poner un prefijo @ para evitar el error. El loadHTML hace el mejor trabajo en mi opinión y es bastante simple:
$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();
Funciona con otro DOMDocument para analizar el código HTML. Pero debe importar los nodos al documento principal para poder usarlos en él:
$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);
}
Y como una función útil:
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);
}
}
Entonces puedes simplemente hacer esto:
$elem = $dom->createElement(''div'');
appendHTML($elem, ''<h1>Hello world</h1>'');
Puedes usar
Ejemplo:
// 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();
Salida:
<?xml version="1.0"?>
<html><body><h1>This is <em>my</em> template</h1></body></html>
Si desea importar desde otro DOMDocument, reemplace las tres líneas con
$tpl = new DOMDocument;
$tpl->loadXml(''<h1>This is <em>my</em> template</h1>'');
$body->appendChild($dom->importNode($tpl->documentElement, TRUE));
Usar TRUE
como el segundo argumento para importNode
hará una importación recursiva del árbol de nodos.
Si necesita importar HTML (mal formado), cambie loadXml
a loadHTML
. Esto desencadenará el analizador HTML de libxml (lo que ext / DOM usa internamente):
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);
Tenga en cuenta que libxml intentará corregir el marcado, por ejemplo, cambiará el cierre incorrecto </h2>
a </h1>
.