Quelle fonction utilisez-vous pour obtenir innerHTML d'un DOMNode donné dans l'implémentation PHP DOM? Quelqu'un peut-il donner une solution fiable?
Bien sûr, externalHTML fera également l'affaire.
Quelle fonction utilisez-vous pour obtenir innerHTML d'un DOMNode donné dans l'implémentation PHP DOM? Quelqu'un peut-il donner une solution fiable?
Bien sûr, externalHTML fera également l'affaire.
Réponses:
Comparez cette variante mise à jour avec 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;
}
?>
Exemple:
<?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
. On peut également vouloir remplacer le trim
par un ltrim
(ou même le supprimer complètement) pour conserver un peu d'espace blanc comme les sauts de ligne.
DOMElement
au lieu d'un DOMNode
comme je passais le retour DOMDocument::getElementById()
. Juste au cas où ça ferait trébucher quelqu'un d'autre.
Pour renvoyer le html
d'un élément, vous pouvez utiliser C14N () :
$dom = new DOMDocument();
$dom->loadHtml($html);
$x = new DOMXpath($dom);
foreach($x->query('//table') as $table){
echo $table->C14N();
}
Une version simplifiée de la réponse de Haim Evgi:
<?php
function innerHTML(\DOMElement $element)
{
$doc = $element->ownerDocument;
$html = '';
foreach ($element->childNodes as $node) {
$html .= $doc->saveHTML($node);
}
return $html;
}
Exemple d'utilisation:
<?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>
*/
Il n'est pas nécessaire de définir preserveWhiteSpace
ou formatOutput
.
En plus de la belle version de trincot avec array_map
et implode
mais cette fois avec array_reduce
:
return array_reduce(
iterator_to_array($node->childNodes),
function ($carry, \DOMNode $child) {
return $carry.$child->ownerDocument->saveHTML($child);
}
);
Je ne comprends toujours pas pourquoi il n'y a pas de reduce()
méthode qui accepte les tableaux et les itérateurs.
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);
}
}
Voici une autre approche basée sur ce commentaire de Drupella sur php.net, qui a bien fonctionné pour mon projet. Il définit le innerHTML()
en créant un nouveau DOMDocument
, en important et en y ajoutant le nœud cible, au lieu d'itérer explicitement sur les nœuds enfants.
Définissons cette fonction d'assistance:
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 );
}
où nous pouvons inclure / exclure la balise cible externe via le deuxième argument d'entrée.
Ici, nous extrayons le HTML interne d'une balise cible donnée par le "premier" attribut id:
$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>
}
Exemple en direct:
http://sandbox.onlinephpfunctions.com/code/2714ea116aad9957c3c437d46134a1688e9133b8
Ancienne requête, mais il existe une méthode intégrée pour le faire. Passez simplement le nœud cible à DomDocument->saveHtml()
.
Exemple complet:
$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);
Production: <p>ciao questa è una <b>prova</b>.</p>