2009-07-20 106 views
5

Necesito eliminar elementos de un archivo XML usando PHP. Se realizará a través de ajax y necesito encontrar el elemento XML a través de un atributo.PHP - Eliminar elemento XML

Este es mi archivo XML

<?xml version="1.0" encoding="utf-8"?> 
<messages> 
    <message time="1248083538"> 
     <name>Ben</name> 
     <email>Ben's Email</email> 
     <msg>Bens message</msg> 
    </message> 
    <message time="1248083838"> 
     <name>John Smith</name> 
     <email>[email protected]</email> 
     <msg>Can you do this for me?</msg> 
    </message> 
</messages> 

Así que lo que diría que es algo así como eliminar el elemento de donde es igual al tiempo 1248083838.

He estado usando XML simple hasta ahora y acabo se dio cuenta de que puede hacer todo excepto borrar elementos.

Entonces, ¿cómo podría hacer esto?

Respuesta

7

Puede usar las clases DOM en PHP. (http://us3.php.net/manual/en/intro.dom.php).

Necesitará leer el documento XML en la memoria, usar las clases DOM para hacer la manipulación, y luego puede guardar el XML según sea necesario (en http o en el archivo).

DOMNode es un objeto que tiene funciones de eliminación (para responder a su pregunta).

Es un poco más complicado que SimpleXML pero una vez que se acostumbre a ella, es mucho más potente

(semi-tomado de un ejemplo de código en php.net)

<?php 

$doc = new DOMDocument; 
$doc->load('theFile.xml'); 

$thedocument = $doc->documentElement; 

//this gives you a list of the messages 
$list = $thedocument->getElementsByTagName('message'); 

//figure out which ones you want -- assign it to a variable (ie: $nodeToRemove) 
$nodeToRemove = null; 
foreach ($list as $domElement){ 
    $attrValue = $domElement->getAttribute('time'); 
    if ($attrValue == 'VALUEYOUCAREABOUT') { 
    $nodeToRemove = $domElement; //will only remember last one- but this is just an example :) 
    } 
} 

//Now remove it. 
if ($nodeToRemove != null) 
$thedocument->removeChild($nodeToRemove); 

echo $doc->saveXML(); 
?> 

Esto debería dar tienes una pequeña idea sobre cómo eliminar el elemento. Imprimirá el XML sin ese nodo. Si desea enviarlo a un archivo, simplemente escriba la cadena en el archivo.

+0

Hmm ... Estoy un poco abrumado por todo lo que hay allí. ¿Podrías explicar un poco más? –

+0

Claro. Voy a editar. –

+0

No tuve la oportunidad de verificar errores de sintaxis menores, pero eso debería darte algo como lo que necesitas. Recomiendo no eliminar al niño en el forloop en sí mismo porque se mete con el contador interno del foreach. –

9

de Dave Morgan es correcto en que las clases DOM son más potentes, pero en caso de que quiera seguir con SimpleXML, intente utilizar la función unset() en cualquier nodo. P.ej. unset ($ simpleXMLDoc-> node1-> child1), y eso se eliminará del XML.

+0

No he intentado hacer eso, pero la lógica dicta que debería funcionar bien. Suena como un trabajo rápido y sucio, pero adecuado para mí. –

+3

No suena rápido y sucio para mí. Suena como la codificación normal. – Tjorriemorrie

1

Aunque SimpleXML no tiene una forma detallada para eliminar los elementos, se puede eliminar elementos de SimpleXML mediante el uso de PHP unset(). La clave para hacerlo es lograr el elemento deseado. Al menos una forma de hacer la orientación es usar el orden de los elementos. En primer lugar averiguar el número de orden del elemento que desea eliminar (por ejemplo, con un bucle), a continuación, quitar el elemento:

$target = false; 
$i = 0; 
foreach ($xml->message as $m) { 
    if ($m['time']=='1248083838') { $target = $i; break; } 
    $i++; 
} 
if ($target !== false) { 
    unset($xml->message[$target]); 
} 

Incluso puede eliminar varios elementos con esto, almacenando el número de orden de los elementos de destino en una matriz. Simplemente recuerde hacer la eliminación en orden inverso (array_reverse($targets)), porque eliminar un artículo reduce naturalmente el número de orden de los artículos que vienen después.

Es cierto que es una especie de hackaround, pero parece funcionar bien.