Lector y escritor de archivos XML versión2.0
El 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 destinada directamente a la extracción de datos del servidor REST de riya, el array generado no trataba bien los datos multidimensionales con mismo campo hermano, así que me he puesto un rato y la he reescrito para extraer todos los datos de una forma mas coherente y de paso darle mas funcionalidad. La función actual tiene 2 modos de funcionamiento. El modo de funcionamiento depende del tipo de datos que se le introduzca de manera que si se introduce un string que contenga la dirección de un archivo en la salida del archivo se dará como resultado un array que contendrá la estructura completa del XML. Si en cambio lo que se introduce es un array procedente de la anterior modalidad generará el contenido XML para posteriormente poder guardarlo.
Como todo esto se ve mejor en ejemplos os dejo un par.
Dentro del primer tipo de uso de la función podemos configurárala en 3 tipos de salida a partir del 2º valor de la función.
-
$datos = xml("ejemplo.xml", "light");
-
$datos = xml("ejemplo.xml", "full");
-
$datos = xml("ejemplo.xml", "clean");
light: Da como resultado un array con los datos valor entre tags y atributos dentro de las tag.
full: Da como resultado un array multidimensional que contiene todos los datos internos y externos de la función.
clean: Da como resultado un array con los datos completos del XML (nombre del tag, valores, numero de linea, indicadores de child...).
Para utilizar la 2º parte de la función se necesita un array como el producido anteriormente. Una vez obtenido el array se introduce en el 1º valor de la función xml() y dará como resultado el texto en formato XML.
-
$xml = xml($datos);
Para que podáis realizar las pruebas y usarla cuando queráis os dejo la función completa:
-
function xml($datos, $mode = ""){
-
if($mode == "REESCRITuRA"){#limpiado de los array
-
$valor = $datos;
-
$dato = $valor; //lo deja
-
} else { //si es un objeto
-
foreach($valor as $key => $valor1){ //lo conteo
-
$dato[] = xml($valor1, "REESCRITuRA"); //
-
} else {
-
$dato[$key] = xml($valor1, "REESCRITuRA"); //
-
}
-
}
-
}
-
return $dato;
-
} else {
-
$simple = str_replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", "<?xml version=\"1.0\" encoding=\"UTF-8\"?><data>", $simple);
-
$simple .= "</data>";
-
//ordenado de las variables
-
#cambio las key originales por su posicion en linea
-
foreach($index as $key => $valor){ //leo las key de los padres de linea
-
foreach($index[$key] as $key_1 => $valor_1){ //leo los numeros de linea
-
$out[$valor_1] = $vals[$valor_1]; //creo un array con los numeros de linea como keys para el ordenado
-
}
-
}
-
#ordeno el array segun salio del arhcivo fuente XML
-
-
#declaro las variables contenedoras de la salida
-
$num = 0;
-
#leo el array del fuente
-
foreach($out as $key => $valor){
-
#por cada open agrego un registro tag a local
-
if($valor["type"] == "open"){
-
$local[] = "[".$valor["tag"]."]"."[".$num."]";
-
}
-
#por cada close busco la ultima aparicion del tag q se cierra y lo elimino
-
if($valor["type"] == "close"){
-
}
-
-
#si no se abre ni se cierra, recorro el array con los local y lo imprimo en forma de ruta/array
-
if($valor["type"] == "complete"){
-
$_datos = "$"."_out";
-
$__datos = "$"."__out";//
-
foreach($local as $ruta){
-
$_datos .= $ruta;
-
$__datos .= $ruta;//
-
}
-
#al terminar el conteo del local construyo el cargador de la ruta del array de salida y lo ejecuto.
-
$_datos .= "[".$valor["tag"]."] = array(\"value\" => $"."valor[\"value\"], \"attributes\" => $"."valor[\"attributes\"]);";
-
$__datos .= "[".$valor["tag"]."] = $"."valor;";//
-
} else {
-
if($valor["type"] == "close"){
-
$num++;
-
}
-
}
-
}
-
//fin ordenado de las variables
-
if($mode == "light" || $mode == ""){//limpio de arrays multiples
-
return xml($_out["DATA"][0], "REESCRITuRA");
-
}
-
if($mode == "full"){//todos los array generados
-
return array("full" => xml($__out["DATA"][0], "REESCRITuRA"), "clean" => xml($_out["DATA"][0], "REESCRITuRA"), "values" => $vals, "lines" => $index, "original" => $simple);
-
}
-
if($mode == "clean"){//pasado por el sistema de ordenado de archivos
-
return xml($__out["DATA"][0], "REESCRITuRA");
-
}
-
} else {#array2xml
-
$array = $datos;
-
$f = $mode;
-
#declaro el encabezado de declaración del XML
-
if($f != "INITIaTE"){
-
$out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
-
}
-
#recorro el array actual obteniendo todos los tag si contiene mas arrays
-
foreach($array as $key => $value){ //recorro los tags repetidos
-
$out_atrib = "";
-
foreach($value["attributes"] as $atrib_name => $atrib){
-
$out_atrib .= " ".$atrib_name."=\"".$atrib."\"";
-
}
-
}
-
$out .= "<".$key.$out_atrib.">".$value["value"]."</".$key.">\n";
-
} else {
-
foreach($value as $_key => $id){ //recorro los contenidos de cada uno de los tag
-
$out .= "<".$key.">\n";
-
$out .= xml($id, "INITIaTE");
-
$out .= "</".$key.">\n";
-
}
-
}
-
}
-
return $out;
-
}
-
}
-
}
El archivo utilizado para el testado de la función ha sido ejemplo.xml situado en la misma carpeta del servidor que el archivo que contenía xml().
El contenido de ejemplo.xml era:
-
<?xml version="1.0" encoding="UTF-8"?>
-
<padre>
-
<hijo>
-
<nombre apellido="gonzalez">paquito</nombre>
-
<cumpleanios>1/11/1980</cumpleanios>
-
<sexo>hombre</sexo>
-
<edad></edad>
-
</hijo>
-
<hijo>
-
<nombre apellido="zuarezz" segundo_apellido="marquez">juanito</nombre>
-
<cumpleanios>1/08/1983</cumpleanios>
-
<sexo>hombre</sexo>
-
<sexo>si, hombre </sexo>
-
<residencia>
-
<calle>c/</calle>
-
<num>c/</num>
-
</residencia>
-
<residencia>
-
<calle>c/</calle>
-
<num>c/</num>
-
</residencia>
-
</hijo>
-
<hija>
-
<nombre apellido="gonzalez">pepita</nombre>
-
<cumpleanios>1/08/1983</cumpleanios>
-
<sexo>mujerr</sexo>
-
</hija>
-
</padre>
-
-
<padre>
-
<tio>
-
<nombre apellido="gonzalez">paquito</nombre>
-
<cumpleanios>1/11/1980</cumpleanios>
-
<sexo>hombre</sexo>
-
<edad></edad>
-
</tio>
-
<sobrino>
-
<nombre apellido="zuarezz">juanito</nombre>
-
<cumpleanios>1/08/1983</cumpleanios>
-
<sexo>hombre</sexo>
-
<sexo>que si, es un hombre </sexo>
-
<residencia>
-
<calle>c/</calle>
-
<num>c/</num>
-
</residencia>
-
<residencia>
-
<calle>c/</calle>
-
<num>c/</num>
-
</residencia>
-
</sobrino>
-
<hija>
-
<nombre apellido="gonzalez">pepa</nombre>
-
<cumpleanios>1/08/1983</cumpleanios>
-
<sexo>mujer</sexo>
-
</hija>
-
</padre>
Que lo disfrutéis.
Actualización: Nueva version de esta Función. Version de XML() 2.5
[...] 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 [...]
[...] Hoy toca otra actualización de una función relativamente antigua. El XML es un lenguaje de almacenamiento de datos principalmente que hoy en día se usa para casi todo, desde las API online, RSS o los principales sistemas de comunicación entre empresas o gobiernos hasta las mas simples galerías de imágenes flash o conversaciones de MSN Messenger utilizan este sistema para encapsular los datos de manera fácil para las maquinas y los humanos. Por esto es un sistema que no podemos dejar de lado en nuestras aplicaciones. Por esto me dispongo a sacar la tercera versión de la función xml(). [...]