Bien, después de haberme atrasado casi un mes y en vista de que es un tema difícil de encontrar en la red, voy a hacer un microtutorial sobre cómo modificar un documento XML usando PHP5. Ya vimos cómo hacer un parsing a un documento XML usando la extensión que provee PHP5 llamada SimpleXMLElement. Ahora veremos primero cómo modificar elementos de nuestro XML, estamos hablando de agregar o eliminar elementos.
Cómo agregar elementos, hijos y atributos
Hasta PHP 5.1.3 la extensión SimpleXMLElement no tenía forma de agregar elementos a un documento XML. Sólo era posible modificar los valores de elementos o atributos pero para agregar nuevos era necesario exportar el objeto SimpleXMLElement a DOM, hacer los cambios y exportar de nuevo a SimpleXMLElement, lo cual era una tarea complicada. Pero la versión 5.1.3 introdujo dos nuevos métodos que nos dan el poder de modificar el documento XML. Me refiero a los métodos:
SimpleXMLElement::addChild()
SimpleXMLElement::addAttribute()
El nombre lo dice todo, con el primero agregamos un elemento hijo al elemento en el que nos encontramos y con el segundo agregamos un atributo. addChild() acepta tres parámetros, el primero indica el nombre del nuevo elemento, el segundo es opcional e indica el valor del elemento, y el tercero también es opcional e indica el namespace al cual pertenece el elemento. addAttribute() recibe dos, el nombre del atributo y su valor.
Pongamos un ejemplo para ilustrar su uso. Recordemos el ejemplo de la vez pasada donde usamos un archivo XML cuyo contenido son libros con sus respectivos datos y pasemos a crear el objeto SimpleXMLElement.
$library = new SimpleXMLElement('library.xml', null, true);
Ahora supongamos que queremos agregar un nuevo libro llamado The finished mistery cuyo autor es J. F. Rutherford, el ISBN es 0812550706 y la editorial es Watchtower Society.
$book = $library->addChild('book');
$book->addAttribute('isbn', '0812550706');
$book->addChild('title', "The finished mistery");
$book->addChild('author', 'J. F. Rutherford');
$book->addChild('publisher', 'Watchtower Society');
Con eso es suficiente para modificar el contenido XML. En la primera línea estamos agregando un nuevo hijo llamado book al elemento raíz que es library, como SimpleXMLElement siempre nos regresa un objeto del mismo tipo, entonces a la variable $book también podemos aplicarle el metodo addChild() para crearle hijos, (que vendrían siendo los nietos de $library). Es como una especie de recursividad, donde podemos ir creando elementos en varios niveles, paras obtener hijos, nietos, bisnietos etc.
Ahora bien, hasta este punto no podemos ver cómo ha quedado nuestro documento XML. Lo siguiente será mostrarlo en el navegador. Para ello, debemos enviar una cabecera para indicar al navegador que el contenido a mostrar no es simple texto ni HTML, sino XML y después hacer la impresión del mismo.
header('Content-type: text/xml');
echo $library->asXML();
¿Para que sirve el método asXML()? regresa el contenido XML del objeto como una cadena, pero solo si lo llamamos sin argumentos. La otra opción, que sin duda es la qué podria darnos mas usabilidad es llamarlo con un parametro que contendría una ruta a un archivo, el cual se escribirá con el contenido XML del objeto. El método asXML($string) regresará un valor de tipo boolean dependiendo del resultado de la operación.
¿Cómo escribir entonces un archivo XML? Supongamos que, una vez agregado el nuevo libro a nuestro archivo de libros queremos guardar los cambios. Lo único que habría que hacer es:
$library->asXML('library.xml');
Y listo, si escribimos el nombre de un archivo que no existe, se crea automaticamente y si ya existe se sobrescribe.
¿Cómo eliminar ahora elementos y atributos de un documento XML?
SimpleXMLElement, no provee ningun metodo para hacerlo, sin embargo sí hay una forma de eliminar hijos. Supongamos que quiero eliminar el libro que acabo de agregar. Como es el elemento book número 6, solo hay que destruir el objeto que pertenece a ese hijo:
$library->book[5] = null;
El cinco es porque los elementos empiezan a contarse desde cero. Sin embargo, hay un inconveniente; esto solo eliminara a los hijos del elemento book y a sus respectivos atributos, pero los atributos que haya al nivel de book permaneceran ahi. Por lo que el atributo isbn seguirá existiendo. Si lo igualamos a null, solo conseguiremos vaciar su valor pero dejando intacto al atributo.
Para remover efectivamente hijos y atributos, debemos exportar el objeto SimpleXMLElement a DOM, donde las funcionalidades de PHP5 para manipular los datos se hacen más poderosas. Hablaré de ello después…
Espero que este microtutorial sea de utilidad para quien necesite manipular datos XML con PHP 5.