Foros del Web » Programando para Internet » PHP »

Parsear un Array a Un XML.

Estas en el tema de Parsear un Array a Un XML. en el foro de PHP en Foros del Web. Hola, gracias a todos. Tengo una duda, como puedo convertir un array en un XML directamente, es decir el camino inverso del XML al Array. ...
  #1 (permalink)  
Antiguo 03/08/2011, 09:38
 
Fecha de Ingreso: junio-2009
Mensajes: 64
Antigüedad: 15 años, 4 meses
Puntos: 6
Parsear un Array a Un XML.

Hola, gracias a todos. Tengo una duda, como puedo convertir un array en un XML directamente, es decir el camino inverso del XML al Array. Cual es la mejor manera.
Muchas Gracias.-..
  #2 (permalink)  
Antiguo 03/08/2011, 09:48
Avatar de Patriarka  
Fecha de Ingreso: enero-2011
Ubicación: Moreno, Buenos Aires, Argentina
Mensajes: 2.851
Antigüedad: 13 años, 9 meses
Puntos: 288
Respuesta: Parsear un Array a Un XML.

con simplexml es "simple"
  #3 (permalink)  
Antiguo 03/08/2011, 09:48
 
Fecha de Ingreso: junio-2008
Ubicación: Armenia- Colombia || El tigre - Venezuela
Mensajes: 34
Antigüedad: 16 años, 5 meses
Puntos: 1
Respuesta: Parsear un Array a Un XML.

Yo uso una clase frankestein combinando varias que he encontrado en la web para trabajar con arrays, te dejo el codigo

Código PHP:
<?PHP
/*************************************************************************/
/* This class stores associative arrays in an xml formated string.       */
/* There's also a function thar retrieves them. If you try to use        */ 
/* xml2array with a general xml, it can fail, since there can be some    */
/* repeated indexes....                                                  */
/*************************************************************************/

/*************************************************************************/
/* Use:
/* 
<?PHP
include('assoc_array2xml.php');
$example_array=array('one'=>'23','two'=>array('subone'=>'22',subtwo=>'233'),'three'=>'2');
$converter= new assoc_array2xml;
$string=$converter->array2xml($example_array);
echo "******\n$string\n********\n";
$array=$converter->xml2array($string);
print_r($array);
?>
 
*/
class assoc_array2xml {
var 
$text;
var 
$arrays$keys$node_flag$depth$xml_parser;
/*Converts an array to an xml string*/
    
function array2xml($array) {
        
//global $text;
        
$this->text="<?xml version=\"1.0\" encoding=\"iso-8859-1\"?><array>";
        
$this->text.= $this->array_transform($array);
        
$this->text .="</array>";
        return 
$this->text;
    }

    function 
array_transform($array){
        
//global $array_text;
        
foreach($array as $key => $value){
            if(!
is_array($value)){
                
$this->text .= "<$key>$value</$key>";
            } else {
                
$this->text.="<$key>";
                
$this->array_transform($value);
                
$this->text.="</$key>";
            }
        }
        return 
$array_text;
    }

    function 
startElement($parser$name$attrs)
    {
       
$this->keys[]=$name//We add a key
       
$this->node_flag=1;
       
$this->depth++;
    }
    function 
characterData($parser,$data)
    {
       
$key=end($this->keys);
       
$this->arrays[$this->depth][$key]=$data;
       
$this->node_flag=0//So that we don't add as an array, but as an element
    
}
    function 
endElement($parser$name)
    {
       
$key=array_pop($this->keys);
       
//If $node_flag==1 we add as an array, if not, as an element
       
if($this->node_flag==1){
         
$this->arrays[$this->depth][$key]=$this->arrays[$this->depth+1];
         unset(
$this->arrays[$this->depth+1]);
       }
       
$this->node_flag=1;
       
$this->depth--;
    }
    
//Returns an array from an xml file.
    
function xml2array($contents$get_attributes=1$priority 'tag') { 
        if(!
$contents) return array(); 

        if(!
function_exists('xml_parser_create')) { 
            
//print "'xml_parser_create()' function not found!"; 
            
return array(); 
        } 

        
//Get the XML parser of PHP - PHP must have this module for the parser to work 
        
$parser xml_parser_create(''); 
        
xml_parser_set_option($parserXML_OPTION_TARGET_ENCODING"UTF-8"); # http://minutillo.com/steve/weblog/2004/6/17/php-xml-and-character-encodings-a-tale-of-sadness-rage-and-data-loss 
        
xml_parser_set_option($parserXML_OPTION_CASE_FOLDING0); 
        
xml_parser_set_option($parserXML_OPTION_SKIP_WHITE1); 
        
xml_parse_into_struct($parsertrim($contents), $xml_values); 
        
xml_parser_free($parser); 

        if(!
$xml_values) return;//Hmm... 

        //Initializations 
        
$xml_array = array(); 
        
$parents = array(); 
        
$opened_tags = array(); 
        
$arr = array(); 

        
$current = &$xml_array//Reference 

        //Go through the tags. 
        
$repeated_tag_index = array();//Multiple tags with same name will be turned into an array 
        
foreach($xml_values as $data) { 
            unset(
$attributes,$value);//Remove existing values, or there will be trouble 

            //This command will extract these variables into the foreach scope 
            // tag(string), type(string), level(int), attributes(array). 
            
extract($data);//We could use the array by itself, but this cooler. 

            
$result = array(); 
            
$attributes_data = array(); 
             
            if(isset(
$value)) { 
                if(
$priority == 'tag'$result $value
                else 
$result['value'] = $value//Put the value in a assoc array if we are in the 'Attribute' mode 
            


            
//Set the attributes too. 
            
if(isset($attributes) and $get_attributes) { 
                foreach(
$attributes as $attr => $val) { 
                    if(
$priority == 'tag'$attributes_data[$attr] = $val
                    else 
$result['attr'][$attr] = $val//Set all the attributes in a array called 'attr' 
                

            } 

            
//See tag status and do the needed. 
            
if($type == "open") {//The starting of the tag '<tag>' 
                
$parent[$level-1] = &$current
                if(!
is_array($current) or (!in_array($tagarray_keys($current)))) { //Insert New tag 
                    
$current[$tag] = $result
                    if(
$attributes_data$current[$tag'_attr'] = $attributes_data
                    
$repeated_tag_index[$tag.'_'.$level] = 1

                    
$current = &$current[$tag]; 

                } else { 
//There was another element with the same tag name 

                    
if(isset($current[$tag][0])) {//If there is a 0th element it is already an array 
                        
$current[$tag][$repeated_tag_index[$tag.'_'.$level]] = $result
                        
$repeated_tag_index[$tag.'_'.$level]++; 
                    } else {
//This section will make the value an array if multiple tags with the same name appear together 
                        
$current[$tag] = array($current[$tag],$result);//This will combine the existing item and the new item together to make an array
                        
$repeated_tag_index[$tag.'_'.$level] = 2
                         
                        if(isset(
$current[$tag.'_attr'])) { //The attribute of the last(0th) tag must be moved as well 
                            
$current[$tag]['0_attr'] = $current[$tag.'_attr']; 
                            unset(
$current[$tag.'_attr']); 
                        } 

                    } 
                    
$last_item_index $repeated_tag_index[$tag.'_'.$level]-1
                    
$current = &$current[$tag][$last_item_index]; 
                } 

            } elseif(
$type == "complete") { //Tags that ends in 1 line '<tag />' 
                //See if the key is already taken. 
                
if(!isset($current[$tag])) { //New Key 
                    
$current[$tag] = $result
                    
$repeated_tag_index[$tag.'_'.$level] = 1
                    if(
$priority == 'tag' and $attributes_data$current[$tag'_attr'] = $attributes_data

                } else { 
//If taken, put all things inside a list(array) 
                    
if(isset($current[$tag][0]) and is_array($current[$tag])) {//If it is already an array... 

                        // ...push the new element into that array. 
                        
$current[$tag][$repeated_tag_index[$tag.'_'.$level]] = $result
                         
                        if(
$priority == 'tag' and $get_attributes and $attributes_data) { 
                            
$current[$tag][$repeated_tag_index[$tag.'_'.$level] . '_attr'] = $attributes_data
                        } 
                        
$repeated_tag_index[$tag.'_'.$level]++; 

                    } else { 
//If it is not an array... 
                        
$current[$tag] = array($current[$tag],$result); //...Make it an array using using the existing value and the new value
                        
$repeated_tag_index[$tag.'_'.$level] = 1
                        if(
$priority == 'tag' and $get_attributes) { 
                            if(isset(
$current[$tag.'_attr'])) { //The attribute of the last(0th) tag must be moved as well 
                                 
                                
$current[$tag]['0_attr'] = $current[$tag.'_attr']; 
                                unset(
$current[$tag.'_attr']); 
                            } 
                             
                            if(
$attributes_data) { 
                                
$current[$tag][$repeated_tag_index[$tag.'_'.$level] . '_attr'] = $attributes_data
                            } 
                        } 
                        
$repeated_tag_index[$tag.'_'.$level]++; //0 and 1 index is already taken 
                    

                } 

            } elseif(
$type == 'close') { //End of tag '</tag>' 
                
$current = &$parent[$level-1]; 
            } 
        } 
         
        return(
$xml_array); 
    }

}
//End of the class

?>
El codigo no es mio, pero me ha funcionado siempre que lo he usado, hay dos funciones para pasar de xml a array y de array a xml.

Espero te sirva
  #4 (permalink)  
Antiguo 03/08/2011, 10:02
Avatar de skywolker  
Fecha de Ingreso: julio-2011
Ubicación: España
Mensajes: 195
Antigüedad: 13 años, 3 meses
Puntos: 8
Pregunta Respuesta: Parsear un Array a Un XML.

Para que sirve esto y como se utiliza?
  #5 (permalink)  
Antiguo 03/08/2011, 10:09
 
Fecha de Ingreso: junio-2009
Mensajes: 64
Antigüedad: 15 años, 4 meses
Puntos: 6
Respuesta: Parsear un Array a Un XML.

Excelente, Necroside, la voy a probar ... yo encontre otra.. y me ha funcionado muy bien tambien...

Por si alguien necesita:

Código PHP:
<?
class ClassXmlArray{
        var 
$encoding'ISO-8859-1';
    var 
$version '1.0';
    var 
$html     false;
    var 
$ln         '';
 
    public function 
array2xml($arr,$file=NULL)
    {     
$xml ='<?xml version="'.$this->version.'" encoding="'.$this->encoding.'" ?>'.$this->ln;
         
$xml.='<rows>';
        
$xml.=$this->arrXml($arr);
        
$xml.='</rows>';
        if(
$file && ($fp=fopen($file,'w')))
        {     
fwrite($fp,$xml); 
            
fclose($fp);  
            return 
true
        }else return 
$xml;
    }
 
    public function 
arrXml($ar)
    {    if(
is_array($ar))
        {    if(
count($ar))
            {    
$xml='';
                foreach(
$ar as $k=>$v)
                {    
$p='';                
                    
$key=is_numeric($k)?'row':$k;
                    if(
is_array($v))
                    {    foreach(
$v as $pk=>$pv)//Propiedades
                        
{    if($pk{0}=='@')
                            {    
$p.=' '.str_replace('@','',$pk).'="'.($pv).'"';
                                unset(
$v[$pk]);
                            }                        
                        } 
$tm=$this->arrXml($v);                                
                    }else 
$tm=$v;
                    
$xml.="<$key$p>".($tm)."</$key>";                                            
                }return 
$xml;    
            }else return 
'';    
        }else return 
$ar;
    }
    public function 
xml2array($file,$html=true)
    {    
$this->html=$html;
        if(
file_exists($file))
        {    
$xxm=simplexml_load_file($file);
            
//return $this->xml2arr($xxm);
            
return $this->_xml2Array($xxm);
            
//print_r($this->_xml2Array($xxm));
        
}else return false;
    }    
 
    public function 
_xml2Array($xml,$attribsAsElements=0)
    {  if (
get_class($xml) == 'SimpleXMLElement'
       {   
$attributes $xml->attributes();
           foreach(
$attributes as $k=>$v) {  if ($v$a[$k] =(string)$v; }
           
$x $xml;
           
$xml get_object_vars($xml);
       }   
       if (
is_array($xml)) 
       {   if (
count($xml) == 0) return (string)$x;
           foreach(
$xml as $key=>$value
           {   
$r[$key] = $this->_xml2Array($value,$attribsAsElements);
               if (!
is_array($r[$key])) $r[$key] = (string)$r[$key];                
           }
           if (isset(
$a)) 
           {  if(
$attribsAsElements$r array_merge($a,$r);
              else 
              {    foreach(
$a as $k=>$v)$r['@'.$k]=(string)$v;                                                                       
                unset(
$r['@attributes']);               
              }
           }
           return 
$r;
       }
       return (string) 
$xml;
    } 
}

//Implementando Prueba 002
$prueba = new ClassXmlArray();
$array = array("nombre" => array("p" =>'nombre1'"e" =>'nombre2'), "nombre2" => array("p" =>'nombre3'"e" =>'nombre4'));
$prueba->array2xml($array,"archi.xml");
?>
Donde el resultado es: el archivo archi.xml generado y:
Código HTML:
<rows><nombre>
<p>nombre1</p>
<e>nombre2</e>
</nombre><nombre2>
<p>nombre3</p>
<e>nombre4</e>
</nombre2>
</rows> 

Muchas Gracias ... Necroside. Despues te comento.

A esta clase le agregue tambien "protected $nodo_principal = 'rows'; " para que pueda seleccionar el nombre del cuerpo.

Última edición por PercevalCiro; 03/08/2011 a las 10:23
  #6 (permalink)  
Antiguo 03/08/2011, 13:46
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 5 meses
Puntos: 1517
Respuesta: Parsear un Array a Un XML.

Hay maneras aún más simples de lograrlo, algo como esto
Código PHP:
Ver original
  1. <?php
  2. function assocArrayToXML($root_element_name,$ar)
  3. {
  4.     $xml = new SimpleXMLElement("<?xml version=\"1.0\"?><{$root_element_name}></{$root_element_name}>");
  5.     $f = create_function('$f,$c,$a','
  6.         foreach($a as $k=>$v) {
  7.             if(is_array($v)) {
  8.                 $ch=$c->addChild($k);
  9.                 $f($f,$ch,$v);
  10.             } else {
  11.                 $c->addChild($k,$v);
  12.             }
  13.         }'
  14.     );
  15.     $f($f,$xml,$ar);
  16.     return $xml->asXML();
  17. }
  18. $arr = array(
  19.     'bar' => array(
  20.         'foo' => 'foo',
  21.         'bar' => 'bar',
  22.         'baz' => 'baz'
  23.     ),
  24.     'baz' => array(
  25.         'foo' => 'foo',
  26.         'bar' => 'bar',
  27.         'baz' => 'baz'
  28.     )
  29. );
  30. echo assocArrayToXML('foo', $arr);
Tomado de http://www.php.net/manual/en/book.simplexml.php#101949
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #7 (permalink)  
Antiguo 03/08/2011, 15:05
Avatar de skywolker  
Fecha de Ingreso: julio-2011
Ubicación: España
Mensajes: 195
Antigüedad: 13 años, 3 meses
Puntos: 8
Respuesta: Parsear un Array a Un XML.

Tengo la duda para que sirve esto alguien me dice?
  #8 (permalink)  
Antiguo 03/08/2011, 15:07
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años, 5 meses
Puntos: 1517
Respuesta: Parsear un Array a Un XML.

Convertir un array a xml. Tal vez sea para pasar los datos de un servidor a otro o algo por el estilo.
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #9 (permalink)  
Antiguo 03/08/2011, 20:05
Avatar de skywolker  
Fecha de Ingreso: julio-2011
Ubicación: España
Mensajes: 195
Antigüedad: 13 años, 3 meses
Puntos: 8
Respuesta: Parsear un Array a Un XML.

hay de todo y para todo ty.
  #10 (permalink)  
Antiguo 05/08/2011, 07:34
 
Fecha de Ingreso: junio-2009
Mensajes: 64
Antigüedad: 15 años, 4 meses
Puntos: 6
Respuesta: Parsear un Array a Un XML.

En mi caso particular, necesitaba recuperar los datos de la meta_data de bases de datos Postgres y guardarlos en archivos XML, y poder verlo. Para hacerlo rapido necesitaba un clase que hiciera eso.

Etiquetas: parsear, rss_php, xml
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 17:38.