De XML a Array con PHP4
De un tiempo a esta parte me dedico básicamente a hacer funciones que faciliten la utilización de los datos de cualquier cosa. Para esto lo mejor según mi experiencia es utilizar array. En php los array son fáciles de implementar, sobre todo para hacer operaciones con muchos datos a la vez, como listas de números, direcciones o lo que sea.
Vista esta necesidad me puse a buscar una función que me pasara competentemente un archivo XML a Array, y encontré que el php tiene una implementada, pero esta implementada desde php5 asi que hasta que los señores de aruba no quieran dar soporte para php5 (dado que php4 ha dejado de tener soporte por parte de sus creadores) me toca sacarme las funciones a maña como siempre. Y aquí os dejo la de hoy.
Es una de las funciones mas simples que existen. Solo tiene 2 parámetros, $url que será la dirección donde se encuentre el archivo XML a leer y $full que indicará si queremos obtener los datos adicionales.
Si ponemos cualquier string (un contenido entre comillas) en $full en nuestro array no aparecerán datos como la linea en la que aparece el elemento representado, su orden en la jerarquía o el tag en el que estaba encerrado el dato entre otros.
Por defecto esta opción está activada, de manera que nos ofrezca el mayor numero de datos posible.
la función es:
-
function xml2array($url, $full=""){
-
//ordenado de las variables
-
foreach($index as $key=>$value){
-
foreach($value as $key1=>$value1){
-
if($full == ""){
-
$out[$key][$key1]["line"] = $value1;
-
}
-
foreach($vals[$value1] as $key2=>$value2){
-
if($key2 == "attributes"){
-
if($full == ""){
-
} else {
-
$out[$key][$key1] = $value2;
-
}
-
} else {
-
if($full == ""){
-
$out[$key][$key1][$key2] = $value2;
-
}
-
}
-
}
-
}
-
}
-
//fin ordenado de las variables
-
return $out;
-
}
Hoy en día muchos de los servicios online ofrecen contenidos XML para revisar los datos... sin ir mas lejos este blog ofrece en XML a través del RSS los post del blog. Pero otros muchos como flickr, gmail.. nos dan soporte para obtener información.
Para la siguiente demostración vamos a ver los datos del RSS de este blog en el array de una forma muy simple:
-
$url = "http://www.tierra0.com/feed/";
-
$resultado = xml2array($url);
Si por ejemplo queremos poner las fotos publicadas en nuestra cuenta de flickr solo tenemos que sacar la dirección del feed de abajo a la izq de nuestra galería y pegarla en la dirección de url como en el siguiente ejemplo y directamente nos creará una mini-galería con imágenes, links y comentario de cada imagen:
-
$url = "http://api.flickr.com/services/feeds/photos_public.gne?id=40962351@N00&lang=en-us&format=rss_200";
-
$resultado = xml2array($url);
-
foreach($resultado["DESCRIPTION"] as $value){
-
}
Otro ejemplo de galería con los datos ofrecidos por flickr:
-
$url = "http://api.flickr.com/services/feeds/photos_public.gne?id=40962351@N00&lang=en-us&format=rss_200";
-
$resultado = xml2array($url);
-
foreach($resultado["MEDIA:CONTENT"] as $key=>$value){
-
}
La aplicación que le estoy intentando dar yo es para reescribir un poco de la API del sistema de almacenamiento de imágenes Riya, el cual posee reconocimiento facial con OCR y viene genial a la hora de hacer búsquedas de fotografías automáticamente.
Actualización: Esta es una función con errores. Para mejorar su funcionamiento y agregarle mayor versatilidad se ha creado la versión 2.0
Para mas información de su funcionamiento y empleo entrad en lector y escritor de archivos XML versión2.0.
Actualización: Nueva version de esta Función. Version de XML() 2.5
Vale muy bien me saca todo el xml, perfecto, ahora como hago para escribir todo eso o coger datos porque no lo consigo de ninguna manera, seguimos con php por supuesto, gracias!
perdon no me explicado bien, quiero coger esos datos y volver a escribirlos en un xml, como lo hago???
es decir paso desde array a xml, gracias!
a ver Fran… si no lo he entendido mal lo que quieres es tomar datos de un archivo XML, cargarlos en un array y al terminar de usar ese array para reescribir ese mismo archivo XML de nuevo no??
Para esto tendrías que, una vez extraído el array pasarlo entero previa modificación de las partes que quieras por una función recursiva que lea todos los array que esten dentro del array principal, dando etiquetas a todos los valores y componiendo el texto del archivo que mas tarde tendrás que escribir dentro del archivo XML de origen.
Para la parte recursiva puedes usar de ejemplo la función “object2array()” que explique en un articulo la semana pasada. Solo tendrías que utilizar las key de los valores a extraer como nombres de las etiquetas para recomponer las partes de texto, cambiando la forma de salida de array a strings.
La otra parte la puedes hacer utilizando la función “archivo()” que describo en un articulo anterior.
[...] comentario de uno de los usuarios, @Fran, me ha echo revisar la función xml2array() y he visto que en una primera versión al hacerla [...]
primero gracias por contestar y ahora al lio, mi problema es que tengo que recoger los datos de un xml enorme con etiquetas que se repiten y no siempre al mismo nivel ni en los mismos nodos, ejemplo, etiqueta foto, dentro etiqueta imagen, y dentro etiqueta orden y referencia, estas 2 últimas con datos, pero la primera etiqueta, foto, la puedes encontrar tanto en un nodo como en otro o dentro de tres nodos, y no consigo referenciarlas o q me lea el xml entero y las distinga, en cuanto encuentra foto por segunda vez me lo graba encima de la primera y me lo pisa, y con tus funciones no lo hace pero yo entiendo como recoger solo los datos sin más con lo que tu has hecho, si me pudieras ayudar te lo agradecería, talue!
Buenas Fran. Si te entendí, y he puesto un pos nuevo con una nueva versión de la función XML. La nueva versión pasa los datos de XML a array y de array a XML, y de paso corrige algunos errores que había sobre las etiquetas repetidas, atributos… Seguro que nos vale mejor a todos.
De todas formas si ves algún fallo más en la versión 2.0 no dudes en contármelo y vemos que se puede hacer.
Muchas gracias así da gusto jejejeje
De nada hombre
Hola otra vez, a ver si me podéis ayudar con esto, necesito modificar una etiqueta de un xml y no lo consigo el tema es cambiar “Hola pedro” por
“Adios Juan” por ejemplo…y chico no consigo, agradecimientos adelantados, talue!
Hola pedro
Perdón no ha salido bien, quiero cambiar, el contenido de la etiqueta texto que tiene como nodo padre mensaje
mensaje
texto
Hola Pedro
texto
mensaje
así mejor ejejje
Buenas Fran. A Ver. No se exactamente que problema tienes pero intentamos solucionarlo. Si tienes un archivo XML lo primero que tienes que revisar es que tenga una correcta cabecera XML. Lo que quiere decir, que empiece arriba del todo por el famoso
<?xml version="1.0" encoding="UTF-8"?>. si no empieza así, ya de antemano no va a funcionar la extracción del XML por que no lo trataría como XML.Si el problema lo tienes al ir hacia el registro, es simplemente dirigirte al registro que quieras, por ejemplo con
$xml["mensaje"][0]["texto"]y sustituirlo como una variable cualquiera o utilizarforeach()para ir de nodo en nodo.Simplemente echo esto solo tienes que volver a meter el registro en la función
xml()y ya funciona.Te dejo un ejemplo para el xml anterior.
$datos = xml("mensajes.xml");//extraigo el xml a un array$datos["mensaje"][0]["texto"] = “Adios Juan”;//cambio el registro texto del nodo 0 de nombre mensajeprint_r(xml($datos));//hago que se vea el array completo con el cambioSi quieres que se guarde en el mismo archivo inténtalo con la funcion archivo() que tengo por el blog.
gracias antares, me has sido de gran ayuda otra vez
De nada hombre pero… ¿que estas montando?
antares500, me fue muy util… muchisimas gracias, muy groso!!…
A partir de tu desarrollo estoy trabajando con el xml de Weather Channel… y es bastante sencillo.
Saludos!!!
Vaphomet666 me alegro que te fuera útil, si terminas la función me encantaría echarle un ojo y si quieres postearla por aquí a tu nombre claro.. Yo hice algo parecido hace un tiempo pero al final lo deje por proyectos mas grandes.
un saludo!
Simple, practico y útil.
Muchas gracias!!
Hola, al parecer es muy buena tu funcion, pero la funcion xml_parse_into_struct ya hacia eso mismo desde el php4… Claro mucho mas enredado, te entrega 2 arrays, uno de indices, y otro de datos.
Saludos!!
Hola Alexis, pues si te digo la verdad no tenia ni idea de que esa función existiera! la verdad es que me ha parecido realmente interesante.. cuando cree esta función la hice para poder leer desde PHP4 xml en formato mas semejante al original pero intentare sacar algo de tiempo para echar un ojo a xml_parse_into_struct() a ver si se me ocurre algo para dejarlo mas ordenado