2010-01-18 16 views
72

¿Qué función usas para obtener innerHTML de un DOMNode dado en la implementación PHP DOM? ¿Alguien puede dar una solución confiable?¿Cómo obtener innerHTML de DOMNode?

Por supuesto outerHTML también lo hará.

Respuesta

118

Compare esta variante actualizada con PHP Manual User Note #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); 
} 
?> 
+0

Gracias. Funciona bien. No debería $ dom-> preserveWhiteSpace = false; estar antes de la carga del documento? – JohnM2

+0

@ JohnM2: [Sí debería] (http://stackoverflow.com/questions/798967/php-simplexml-how-to-save-the-file-in-a-formatted-way). – hakre

+0

Notas adicionales: desde PHP 5.3.6 puede ahorrar el 'DOMDocument' temporal. También es posible que desee reemplazar el 'trim' con un' ltrim' (o incluso eliminarlo por completo) para conservar un poco del espacio en blanco como saltos de línea. – hakre

3
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); 
    } 
} 
6

Para devolver el html de un elemento, puede utilizar C14N():

$dom = new DOMDocument(); 
$dom->loadHtml($html); 
$x = new DOMXpath($dom); 
foreach($x->query('//table') as $table){ 
    echo $table->C14N(); 
} 
+2

C14N intentará convertir el HTML a un XML válido. Por ejemplo
se convertirá en

ajaybc

+0

Es una manera sucia de volcar el HTML del elemento, sin tener que usar saveHTML que arrojará etiquetas html, head y body. –

3

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; 
} 

Ejemplo de uso:

<?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 hay necesidad de establecer preserveWhiteSpace o formatOutput.

14

Aquí es una versión en un estilo programación funcional:

function innerHTML($node) { 
    return implode(array_map([$node->ownerDocument,"saveHTML"], 
          iterator_to_array($node->childNodes))); 
} 
4

Además de 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); 
    } 
); 
no hacer

Aún Entiendo, por qué no hay un método reduce() que acepte matrices e iteradores por igual.