¿Qué función usa para obtener innerHTML de un DOMNode dado en la implementación PHP DOM? ¿Alguien puede dar una solución confiable?
Por supuesto, el HTML externo también lo hará.
¿Qué función usa para obtener innerHTML de un DOMNode dado en la implementación PHP DOM? ¿Alguien puede dar una solución confiable?
Por supuesto, el HTML externo también lo hará.
Respuestas:
Compare esta variante actualizada con la nota de usuario del manual PHP # 89718 :
<?php
function DOMinnerHTML(DOMNode $element)
{
$innerHTML = "";
$children = $element->childNodes;
foreach ($children as $child)
{
$innerHTML .= $element->ownerDocument->saveHTML($child);
}
return $innerHTML;
}
?>
Ejemplo:
<?php
$dom= new DOMDocument();
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->load($html_string);
$domTables = $dom->getElementsByTagName("table");
// Iterate over DOMNodeList (Implements Traversable)
foreach ($domTables as $table)
{
echo DOMinnerHTML($table);
}
?>
DOMDocument
. También es posible que desee reemplazar el trim
con un ltrim
(o incluso eliminarlo por completo) para preservar un poco del espacio en blanco como saltos de línea.
DOMElement
lugar de un DOMNode
como estaba pasando el retorno DOMDocument::getElementById()
. Por si acaso tropieza con alguien más.
Para devolver el html
de un elemento, puede usar C14N () :
$dom = new DOMDocument();
$dom->loadHtml($html);
$x = new DOMXpath($dom);
foreach($x->query('//table') as $table){
echo $table->C14N();
}
Una versión simplificada de la respuesta de Haim Evgi:
<?php
function innerHTML(\DOMElement $element)
{
$doc = $element->ownerDocument;
$html = '';
foreach ($element->childNodes as $node) {
$html .= $doc->saveHTML($node);
}
return $html;
}
Uso de ejemplo:
<?php
$doc = new \DOMDocument();
$doc->loadHTML("<body><div id='foo'><p>This is <b>an <i>example</i></b> paragraph<br>\n\ncontaining newlines.</p><p>This is another paragraph.</p></div></body>");
print innerHTML($doc->getElementById('foo'));
/*
<p>This is <b>an <i>example</i></b> paragraph<br>
containing newlines.</p>
<p>This is another paragraph.</p>
*/
No es necesario configurar preserveWhiteSpace
o formatOutput
.
Además de la bonita versión de trincot con array_map
y implode
pero esta vez con array_reduce
:
return array_reduce(
iterator_to_array($node->childNodes),
function ($carry, \DOMNode $child) {
return $carry.$child->ownerDocument->saveHTML($child);
}
);
Todavía no entiendo por qué no hay un reduce()
método que acepte matrices e iteradores por igual.
function setnodevalue($doc, $node, $newvalue){
while($node->childNodes->length> 0){
$node->removeChild($node->firstChild);
}
$fragment= $doc->createDocumentFragment();
$fragment->preserveWhiteSpace= false;
if(!empty($newvalue)){
$fragment->appendXML(trim($newvalue));
$nod= $doc->importNode($fragment, true);
$node->appendChild($nod);
}
}
Aquí hay otro enfoque basado en este comentario de Drupella en php.net, que funcionó bien para mi proyecto. Define el innerHTML()
al crear un nuevo DOMDocument
, importar y agregarle el nodo de destino, en lugar de iterar explícitamente sobre los nodos secundarios.
Definamos esta función auxiliar:
function innerHTML( \DOMNode $n, $include_target_tag = true ) {
$doc = new \DOMDocument();
$doc->appendChild( $doc->importNode( $n, true ) );
$html = trim( $doc->saveHTML() );
if ( $include_target_tag ) {
return $html;
}
return preg_replace( '@^<' . $n->nodeName .'[^>]*>|</'. $n->nodeName .'>$@', '', $html );
}
donde podemos incluir / excluir la etiqueta de destino externa a través del segundo argumento de entrada.
Aquí extraemos el HTML interno para una etiqueta de destino dada por el atributo de identificación "primer":
$html = '<div id="first"><h1>Hello</h1></div><div id="second"><p>World!</p></div>';
$doc = new \DOMDocument();
$doc->loadHTML( $html );
$node = $doc->getElementById( 'first' );
if ( $node instanceof \DOMNode ) {
echo innerHTML( $node, true );
// Output: <div id="first"><h1>Hello</h1></div>
echo innerHTML( $node, false );
// Output: <h1>Hello</h1>
}
Ejemplo en vivo:
http://sandbox.onlinephpfunctions.com/code/2714ea116aad9957c3c437d46134a1688e9133b8
Consulta antigua, pero hay un método integrado para hacerlo. Simplemente pase el nodo de destino a DomDocument->saveHtml()
.
Ejemplo completo:
$html = '<div><p>ciao questa è una <b>prova</b>.</p></div>';
$dom = new DomDocument($html);
@$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
$node = $xpath->query('.//div/*'); // with * you get inner html without surrounding div tag; without * you get inner html with surrounding div tag
$innerHtml = $dom->saveHtml($node);
var_dump($innerHtml);
Salida: <p>ciao questa è una <b>prova</b>.</p>