2011-01-06 12 views
7

Decir que tengo el siguiente código HTML¿Cómo puedo usar XPath y DOM para reemplazar un nodo/elemento en php?

$html = ' 
<div class="website"> 
    <div> 
     <div id="old_div"> 
      <p>some text</p> 
      <p>some text</p> 
      <p>some text</p> 
      <p>some text</p> 
      <div class="a class"> 
       <p>some text</p> 
       <p>some text</p> 
      </div> 
     </div> 
     <div id="another_div"></div> 
    </div> 
</div> 
'; 

Y quiero reemplazar #old_div con lo siguiente:

$replacement = '<div id="new_div">this is new</div>'; 

para dar un resultado final:

$html = ' 
<div class="website"> 
     <div> 
      <div id="new_div">this is new</div> 
      <div id="another_div"></div> 
     </div> 
    </div> 
'; 

¿Hay una forma fácil función de cortar y pegar para hacer esto con PHP?


código de trabajo final gracias a la ayuda de todo de Gordon:

<?php 

$html = <<< HTML 
<div class="website"> 
    <div> 
     <div id="old_div"> 
      <p>some text</p> 
      <p>some text</p> 
      <p>some text</p> 
      <p>some text</p> 
      <div class="a class"> 
       <p>some text</p> 
       <p>some text</p> 
      </div> 
     </div> 
     <div id="another_div"></div> 
    </div> 
</div> 
HTML; 

$dom = new DOMDocument; 
$dom->loadXml($html); // use loadHTML if it's invalid XHTML 

//create replacement 
$replacement = $dom->createDocumentFragment(); 
$replacement ->appendXML('<div id="new_div">this is new</div>'); 

//make replacement 
$xp = new DOMXPath($dom); 
$oldNode = $xp->query('//div[@id="old_div"]')->item(0); 
$oldNode->parentNode->replaceChild($replacement , $oldNode); 
//save html output 
$new_html = $dom->saveXml($dom->documentElement); 

echo $new_html; 

?> 
+1

posible duplicado de [Usando DOMXPath para reemplazar un nodo mientras se mantiene su posición ...] (http://stackoverflow.com/questions/640815/using-domxpath-to-replace-a-node-while- maintain-its-position) – Gordon

+1

Puede usar ** XPath para seleccionar ** el nodo de destino ** para reemplazar con un método DOM **. Título refractante –

Respuesta

11

Dado que la respuesta en el duplicado vinculado no es tan amplia, voy a dar un ejemplo:

$dom = new DOMDocument; 
$dom->loadXml($html); // use loadHTML if its invalid (X)HTML 

// create the new element 
$newNode = $dom->createElement('div', 'this is new'); 
$newNode->setAttribute('id', 'new_div'); 

// fetch and replace the old element 
$oldNode = $dom->getElementById('old_div'); 
$oldNode->parentNode->replaceChild($newNode, $oldNode); 

// print xml 
echo $dom->saveXml($dom->documentElement); 

Técnicamente, no necesita XPath para esto. Sin embargo, puede suceder que su versión de libxml no pueda hacer getElementById para documentos no validados (id attributes are special in XML). En ese caso, vuelva a colocar la llamada a getElementById con

$xp = new DOMXPath($dom); 
$oldNode = $xp->query('//div[@id="old_div"]')->item(0); 

Demo on codepad


Para crear un $newNode con nodos secundarios sin tener que crear y añadir elementos, uno por uno, puede hacerlo

$newNode = $dom->createDocumentFragment(); 
$newNode->appendXML(' 
<div id="new_div"> 
    <p>some other text</p> 
    <p>some other text</p> 
    <p>some other text</p> 
    <p>some other text</p> 
</div> 
'); 
+0

¡Gracias increíble Gordon, lo intentaré ahora! – Haroldo

+0

@gordon 'Error fatal capturable: el argumento 2 pasado a DOMNode :: replaceChild() debe ser una instancia de DOMNode, nulo dado en C: \ wamp \ www \ gv2010 \ user_area \ replacement-test.php en la línea 24'? – Haroldo

+0

@Haroldo actualizado. lo siento, no presté atención. – Gordon

-7

use jquery hide() primero para ocultar un div en particular y luego use append para agregar el nuevo div

$('#div-id').remove(); 
$('$div-id').append(' <div id="new_div">this is new</div>'); 
+2

Una pregunta es sobre PHP (lado del servidor), no javascript (lado del cliente). –

+3

más, incluso si esto fuera del lado del cliente, su solución es incorrecta porque se agrega en lugar de reemplazar, por lo que no se conservaría ... – Haroldo

Cuestiones relacionadas