Funcion XML reparada y mejoradaUna de las funciones que mas juego me ha dado últimamente para interactuar con los diferentes servicios de las webs 2.0 ha sido la función xml() y por eso le ha tocado otra actualización. Esta ultima actualización a la version 2.5 añade un nuevo tipo de limpiado del array resultante. Si el condigo XML que intentamos obtener solo utiliza valores y no atributos en los tag es innecesario utilizar dichos datos, al igual que si solo utiliza atributos en vez de valores. A fin de reducir el array resultante algo mas he añadido un nuevo sistema de limpiado que junto con "light" hace del resultado algo mas liviano para el lector. Se trata del modificador "slim". un ejemplo:

PHP:
  1. $datos = xml($archivo, "slim");
  2. print_r($datos);

Ademas se le ha añadido otra nueva mejora. Antes el primer valor, solo podí­a ser un array, en el caso de que se quisiera pasar ese array a XML o una dirección de un archivo que contení­a el XML. En la actual revisión ademas también detecta cuando se le da un texto en XML directamente como string y lo trata como si el contenido de un archivo se tratase.

Funcion xml() version 2.5

PHP:
  1. function xml($datos, $mode = ""){
  2.     if(substr($mode, 0, 11) == "REESCRITuRA"){#limpiado de los array
  3.         if($mode == "REESCRITuRA"){
  4.             $valor = $datos;
  5.             if(!(is_array($valor) || is_object($valor))){ //si no es un objeto ni un array
  6.                 if($valor == ""){
  7.                     $dato = " ";
  8.                 } else {
  9.                     $dato = $valor;//lo deja
  10.                 }
  11.             } else { //si es un objeto
  12.                 foreach($valor as $key => $valor1){ //lo conteo
  13.                     if(is_int($key)){
  14.                         $dato[]  = xml($valor1, $mode); //
  15.                     } else {
  16.                         $dato[$key] = xml($valor1, $mode); //
  17.                     }
  18.                 }
  19.             }
  20.         } else { //compresion del array
  21.             $valor = $datos;
  22.             if(!(is_array($valor) || is_object($valor))){ //si no es un objeto ni un array
  23.                 if($valor == ""){
  24.                     $dato = "";
  25.                 } else {
  26.                     $dato = $valor;//lo deja
  27.                 }
  28.             } else { //si es un objeto o un array
  29.                 foreach($valor as $key => $valor1){ //lo conteo
  30.                     if($valor1["value"] != ""){
  31.                         if($valor1["attributes"] == "" || $valor1["attributes"] == " "){
  32.                             if($valor1["value"] == " "){
  33.                                 $dato[$key] = "";//le cambio x el value
  34.                             } else {
  35.                                 $dato[$key] = $valor1["value"];//le cambio x el value
  36.                             }
  37.                         } else {
  38.                             $dato[$key] = xml($valor1, $mode);//le dejo como esta
  39.                         }
  40.                     } else {
  41.                         if($valor1["attributes"] != ""){
  42.                             if($valor1["attributes"] == " "){
  43.                                 $dato[$key] = "";//le cambio x el attributes
  44.                             } else {
  45.                                 $dato[$key] = $valor1["value"];//le cambio x el value
  46.                             }
  47.                         } else {
  48.                             $dato[$key] = xml($valor1, $mode);//le dejo como esta
  49.                         }
  50.                     }
  51.                 }
  52.             }
  53.         }
  54.         return $dato;
  55.     } else {#parseador de array
  56.         if(!is_array($datos)){#xml2array
  57.             if(strpos($datos, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>")){
  58.                 $simple = @file_get_contents($datos);
  59.             } else {
  60.                 $simple = $datos;
  61.             }
  62.             $simple = str_replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", "<?xml version=\"1.0\" encoding=\"UTF-8\"?><data>", $simple);
  63.             $simple .= "</data>";
  64.             $p = xml_parser_create();
  65.             xml_parse_into_struct($p, $simple, $vals, $index);
  66.             xml_parser_free($p);
  67.             //ordenado de las variables
  68.             #cambio las key originales por su posicion en linea
  69.             foreach($index as $key => $valor){ //leo las key de los padres de linea
  70.                 foreach($index[$key] as $key_1 => $valor_1){ //leo los numeros de linea
  71.                     $out[$valor_1] = $vals[$valor_1]; //creo un array con los numeros de linea como keys para el ordenado
  72.                 }
  73.             }
  74.             #ordeno el array segun salio del arhcivo fuente XML
  75.             ksort($out); //ordeno los resultados como salieron del archivo XML fuente
  76.             #declaro las variables contenedoras de la salida
  77.             $_out = $local = array();
  78.             $num = 0;
  79.             #leo el array del fuente
  80.             foreach($out as $key => $valor){
  81.                 #por cada open agrego un registro tag a local
  82.                 if($valor["type"] == "open"){
  83.                     $local[] = "[".$valor["tag"]."]"."[".$num."]";
  84.                 }
  85.                 #por cada close busco la ultima aparicion del tag q se cierra y lo elimino
  86.                 if($valor["type"] == "close"){
  87.                     array_pop($local);
  88.                 }
  89.                 #si no se abre ni se cierra, recorro el array con los local y lo imprimo en forma de ruta/array
  90.                 if($valor["type"] == "complete"){
  91.                     $_datos   = "$"."_out";
  92.                     $__datos        = "$"."__out";//
  93.                     foreach($local as $ruta){
  94.                         $_datos  .=  $ruta;
  95.                         $__datos    .=  $ruta;//
  96.                     }
  97.                     #al terminar el conteo del local construyo el cargador de la ruta del array de salida y lo ejecuto.
  98.                     $_datos   .= "[".$valor["tag"]."] = array(\"value\" => $"."valor[\"value\"], \"attributes\" => $"."valor[\"attributes\"]);";
  99.                     $__datos        .= "[".$valor["tag"]."] = $"."valor;";//
  100.                     eval($_datos);
  101.                     eval($__datos);//
  102.                 } else {
  103.                     if($valor["type"] == "close"){
  104.                         $num++;
  105.                     }
  106.                 }
  107.             }
  108.             //fin ordenado de las variables
  109.             if($mode == "slim"){//limpio de arrays multiples
  110.                 return xml(xml($_out["DATA"][0], "REESCRITuRA"), "REESCRITuRA-clean");
  111.             }
  112.             if($mode == "light" || $mode == ""){//limpio de arrays multiples
  113.                 return xml($_out["DATA"][0], "REESCRITuRA");
  114.             }
  115.             if($mode == "full"){//todos los array generados
  116.                 return array("full" => xml($__out["DATA"][0], "REESCRITuRA"), "clean" => xml($_out["DATA"][0], "REESCRITuRA"), "values" => $vals, "lines" => $index, "original" => $simple);
  117.             }
  118.             if($mode == "clean"){//pasado por el sistema de ordenado de archivos
  119.                 return xml($__out["DATA"][0], "REESCRITuRA");
  120.             }
  121.         } else {#array2xml
  122.             $array = $datos;
  123.             $f = $mode;
  124.             #declaro el encabezado de declaraci?n del XML
  125.             if($f != "INITIaTE"){
  126.                 $out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
  127.             }
  128.             #recorro el array actual obteniendo todos los tag si contiene mas arrays
  129.             foreach($array as $key => $value){ //recorro los tags repetidos
  130.                 if(array_key_exists("value", $value)){
  131.                     $out_atrib = "";
  132.                     if(count($value["attributes"])>0){
  133.                         foreach($value["attributes"] as $atrib_name => $atrib){
  134.                             $out_atrib .= " ".$atrib_name."=\"".$atrib."\"";
  135.                         }
  136.                     }
  137.                     $out .= "<".$key.$out_atrib.">".$value["value"]."</".$key.">\n";
  138.                 } else {
  139.                     foreach($value as $_key => $id){ //recorro los contenidos de cada uno de los tag
  140.                         $out .= "<".$key.">\n";
  141.                         $out .= xml($id, "INITIaTE");
  142.                         $out .= "</".$key.">\n";
  143.                     }
  144.                 }
  145.             }
  146.             return $out;
  147.         }
  148.     }
  149. }

Actualización: Nueva version de esta Función. Version de XML() 3.0