(1 votos)

He aquí unas funciones que me he hecho para manejarme con el xml (basadas en simplexml).

Leer xml: Sirve para leer un código xml de un fichero

<?php 
function leer_xml($fichero){ 
//Comprobamos que existe el fichero 
if (file_exists($fichero)) { 
//Lo cargamos como objeto con simplexml 
$dom = simplexml_load_file($fichero); 
} 
else{ 
echo 'Fallo al abrir '.$fichero.'<br/>'; 
$dom = -1; 
} 
 
if(!$dom) return -1; 
return $dom; 
} 
?>

Una alternativa sería para leer xml desde una variable:

 <?php       
 function leer_xml ( $xml ){       
 //Comprobamos que existe la       variable       
 if ( $xml ) {       
 //Lo cargamos como objeto con       simplexml       
 $dom = simplexml_load_string ( $xml );        
}        
else{       
echo 'Fallo al leer el       código<br/>' ;       
 $dom = - 1 ;       
}       
 
if(! $dom ) return - 1 ;       
return $dom ;       
}       
 ?> 

Función insertar_nodo: Añade un nodo/hijo a la estructura xml

 <?php       
 function insertar_nodo ( $nodo , $datos , $fichero , $duplicar , $duplicados ){  
  //Leemos fichero       
 if(( $xml = leer_xml ( $fichero )) == - 1 ) return - 1 ;       
  
  //Comprobamos si puede haber       nodos duplicados o no y si los hay       
 if( $duplicar == 0 ) $stop = buscar_nodo ( $nodo , $duplicados , $fichero );       
 else $stop = 0 ;       
  
  //Si no hay nodos duplicados o       si puede haberlos, seguimos       
 if( $stop == 0 ){       
 //Guardamos todos los datos en       un nuevo nodo       
 $tag = $xml -> addChild ( $nodo );  
  foreach( $datos as $valor ) $tag -> addChild ( $valor [ 'tag' ], $valor [ 'dato' ]);       
 //Guardamos el fichero       
 $xml -> asXML ( $fichero );       
 }       
 
 return 0 ;       
}       
 ?> 

Buscar nodo: Busca dentro de los nodos de un xml

 <?php       
 function buscar_nodo ( $nodo , $datos , $fichero , $case_sensitive ){       
 
 $encontrado = 0 ;       
 //Leemos el fichero       
 if(( $xml = leer_xml ( $fichero )) == - 1 ) return - 1 ;       
  
  //Comprobamos si es case       sensitive       
 if(! $case_sensitive ) $case_sensitive = 0 ;  
  switch( $case_sensitive ){       
 case 0 :       
 //Recorremos los nodos       
 foreach( $xml -> $nodo as $tag )       
 foreach( $datos as $valor )       
 //Comparamos valor del nodo con       el nuestro       
 if( strtolower ( $tag -> $valor [ 'tag' ]) == strtolower ( $valor [ 'dato' ])) $encontrado = 1 ;       
 break;       
 case 1 :  
  foreach( $xml -> $nodo as $tag )       
 foreach( $datos as $valor )       
 if( $tag -> $valor [ 'tag' ] == $valor [ 'dato' ]) $encontrado = 1 ;       
 break;  
  }       
 
 return $encontrado ;       
}       
 ?> 

Modificar nodo: Modifica los valores de un nodo:

 

 
 <?php       
 function modificar_nodo ( $tag , $dato , $viejo , $nuevo , $fichero ){       
 //Leemos el fichero       
 if(( $xml = leer_xml ( $fichero )) == - 1 ) return - 1 ;       
 //Recorremos los nodos        
 foreach( $xml -> $tag as $nodo ){       
 //Si encontramos nuestro nodo       
 if( $nodo -> $dato == $viejo ){       
 //Lo modificamos       
 $nodo -> $dato = $nuevo ;       
 $guardar = 1 ;  
  }       
 }       
 //Si hay cambios guardamos el       fichero        
 if( $guardar ) $xml -> asXML ( $fichero );       
  
  return 0 ;       
}       
 ?> 

Borrar nodo: Busca un valor en los nodos y si lo encuentra, borra el nodo entero

 <?php       
 function borrar_nodo ( $tag , $dato , $valor , $fichero , $num_nodos ){       
 if(! $num_nodos ) $num_nodos = 1 ;       
  
  //Creamos un bucle con una       iteración para cada nodo a borrar       
 for( $i = 0 ; $i < $num_nodos ; $i ++){       
 //Leemos el fichero       
 if(( $xml = leer_xml ( $fichero )) == - 1 ) return - 1 ;       
 //Recorreoms los nodos       
 foreach( $xml -> $tag as $nodo ){       
 //Si el valor del       nodo->etiqueta = valor pasado       
 if( $nodo -> $dato == $valor ) {       
 //Borramos el nodo       
 $dom = dom_import_simplexml ( $nodo );       
 $dom -> parentNode -> removeChild ( $dom );       
 $guardar = 1 ;  
  }       
 }       
 //Si hay cambios guardamos el       fichero       
 if( $guardar ) $xml -> asXML ( $fichero );  
  }       
}       
 ?> 

Borrar nodo con case sensitive:

 <?php       
 function borrar_nodo ( $tag , $dato , $valor , $fichero , $num_nodos , $case_sensitive ){       
 if(! $num_nodos ) $num_nodos = 1 ;       
 if(! $case_sensitive ) $case_sensitive = 0 ;       
  
  switch( $case_sensitive ){       
 case 0 :       
 //Creamos un bucle con una       iteración para cada nodo a borrar       
 for( $i = 0 ; $i < $num_nodos ; $i ++){       
 //Leemos el fichero       
 if(( $xml = leer_xml ( $fichero )) == - 1 ) return - 1 ;       
 //Recorreoms los nodos       
 foreach( $xml -> $tag as $nodo ){       
 //Si el valor del       nodo->etiqueta = valor pasado       
 if( strtolower ( $nodo -> $dato ) == strtolower ( $valor )) {       
 //Borramos el nodo       
 $dom = dom_import_simplexml ( $nodo );       
 $dom -> parentNode -> removeChild ( $dom );       
 $guardar = 1 ;  
  }       
 }       
 //Si hay cambios guardamos el       fichero       
 if( $guardar ) $xml -> asXML ( $fichero );  
  }       
 break;       
 case 1 :       
 //Creamos un bucle con una       iteración para cada nodo a borrar       
 for( $i = 0 ; $i < $num_nodos ; $i ++){       
 //Leemos el fichero       
 if(( $xml = leer_xml ( $fichero )) == - 1 ) return - 1 ;       
 //Recorreoms los nodos       
 foreach( $xml -> $tag as $nodo ){       
 //Si el valor del       nodo->etiqueta = valor pasado       
 if( $nodo -> $dato == $valor ) {       
 //Borramos el nodo       
 $dom = dom_import_simplexml ( $nodo );       
 $dom -> parentNode -> removeChild ( $dom );       
 $guardar = 1 ;  
  }       
 }       
 //Si hay cambios guardamos el       fichero       
 if( $guardar ) $xml -> asXML ( $fichero );  
  }       
 break;       
 }  
}       
 ?> 

Manejo de las funciones:
leer_xml:le pasas la dirección de un fichero que contiene la estructura xml.

insertar_nodo:le pasas la etiqueta padre del nodo, una estructura con datos, el ficheor a leer, si puede haber nodos duplicados y un vector con la información de las etiquetas a mirar para ver si es duplicado.
La estructura de datos será:
$datos[0]['tag'] = 'etiqueta1';
$datos[0]['dato'] = $valor;
$datos[1]['tag'] = 'etiqueta2';
$datos[1]['dato'] = $valor2;
La estructura de valores duplicados es igual, es decir, para cada etiqueta a mirar creas $duplicados ['tag'] = 'etiqueta a mirar a la hora de ver si es duplicado', $duplicados ['dato'] = 'valor a comparar';

buscar_nodo:le pasas la etiqueta padre, la estructura de datos a buscar (idéntica a las estructuras de insertar_nodo), el fichero donde está el xml y si es case sensitive, es decir, si debe tener en cuenta o no las mayúsculas). Este último parámetro ha de ser 0 para que no tenga en cuenta si son mayúsculas o minúsculas y debe ser 1 si se quiere que diferencie mayúsculas de minúsculas. El valor es opcional. Si no se le pasa vale 0.

modificar_nodo:le pasas la etiqueta padre, la sub_etiqueta a cambiar(igual que en funciones anteriores), el valor viejo que debe buscar para cambiarlo, el valor nuevo que debe poner y el fichero a leer.

borrar_nodo:le pasas la etiqueta padre, la sub_etiqueta a mirar para ver si es el nodo a borrar, el dato que debe contener esta etiqueta, el fichero y por último el número máximo de nodos a borrar en caso de que exista más de uno que cumpla el criterio.

Se nota que están recien sacadas del horno ya que las primeras reciben el primer parámetro como $nodo y las últimas como $tag... funcionar funcionan bien, lo que puede que les falte son nombres más coherentes a las variables. Lo dicho, se aceptan correcciones.

Y ahora el ejemplo práctico:

Estructura xml:

<?xml version="1.0" encoding="iso-8859-1"?>   
<usuarios>   
<usuario>   
<nombre>Neo</nombre>   
<password>4028a0e356acc947fcd2bfbf00cef11e128d484a</password>   
<grupo>1</grupo>   
</usuario>   
<usuario>   
<nombre>Neo</nombre>   
<password>d554901301fe8447a1dd696ae7047e589b84bc13</password>   
<grupo>2</grupo>   
</usuario>   
<usuario>   
<nombre>Neo2</nombre>   
<password>7d653cf00d747a9fbab213b6c2b335cfe8199ff3</password>   
<grupo>3</grupo>   
</usuario>   
<usuario>   
<nombre>Neo3</nombre>   
<password>0821b1111851959bfd9f4f9e5e4a60b9a3cdfe16</password>   
<grupo>1</grupo>   
</usuario>   
</usuarios>

Para insetar un nuevo usuario, con nombre "Neo4" y cotraseña "test" (las del ejemplo están codificadas pero aquí lo dejaremos en texto plano) con el grupo "2" sería así:

Valores a insertar:
$usuario = "Neo4";
$pass = "test";
$grupo = "2";

Estructura con valores a insertar:
$datos[0]['tag'] = 'nombre';
$datos[0]['dato'] = $nombre;
$datos[1]['tag'] = 'password';
$datos[1]['dato'] = $pass;
$datos[2]['tag'] = 'grupo';
$datos[2]['dato'] = $grupo;

Estructura con datos para verificar datos duplicados:
$duplicados[0]['tag'] = 'nombre';
$duplicados[0]['dato'] = $nombre;

El cuarto valor es un "1" para indicar que no puede haber nodos duplicados.

insertar_nodo("usuario",$datos,"includes/usuarios.xml",1,$duplicados);

Vamos a buscar si existe "Neo4" en el archivo de usuarios, sin tener en cuenta mayúsculas de minúsculas:

Creamos la estructura que indica las etiquetas a mirar y sus valores:
$vec[0]['tag'] = "nombre";
$vec[0]['dato'] = "neo4";

$existe_nodo = buscar_nodo("usuario",$vec,"includes/usuarios.xml");

No le pasamos el parámetro final, así que por defecto coje un 0 y por tanto no tiene en cuenta las mayúsculas y minúsculas.

Ahora cambiamos "Neo4" por "Neo5":
modificar_nodo("usuario","nombre","Neo4","Neo5","includes/usuarios.xml");

Ahora borramos Neo5:
borrar_nodo("usuario","nombre","Neo5","includes/usuarios.xml",5);

 


Errores y correcciones:

- A las funciones modificar_nodo y borrar_nodo les falta el parámetro $case_sensitive para poder o no tener en cuenta las mayúsculas/minúsculas
- He añadido borra_nodo con case sensitive, pero no la he probado (creo que si que irá bien). La pega es que has de pasarle sí o sí el número de nodos a borrar si quieres usar case_sensitive.
- La función modificar nodo modifica todos los nodos que encuentre que coincidan con el valor dado. Es case sensitive (de momento).

 

Tags:
Comentarios (0)
¡Sólo los usuarios registrados pueden escribir comentarios!