Sigueme por RSS! RSS

Accediendo a los XML desde PHP (simpleXML)


En un post anterior estuvimos repasando el XML, habíamos dicho que:
"A diferencia del HTML, XML no se centra en la representación de la información, si no, en la información en si misma, garantiza que los datos sean independientes de aplicaciones o de fabricantes".

Con PHP podemos acceder a la información albergada en dichos documentos, nos basaremos en el siguiente XML (xml_ejemplo.xml) para los paradigmas:
(clic para mostrar/ocultar)
<?xml version="1.0" encoding="UTF-8"?>
<cursos>
    <curso id="1">
      <name>Curso A</name>
      <alumno dni="V-6432123">
         <nombre>María</nombre>
         <apellido>Bolivar</apellido>
         <fechanac>1990-12-25</fechanac>
         <sexo>Femenino</sexo>
      </alumno>
      <alumno dni="V-9544321">
         <nombre>José</nombre>
         <apellido >García</apellido>
         <fechanac>1991-02-12</fechanac>
         <sexo>Masculino</sexo>
      </alumno>
      <alumno dni="V-15456737">
         <nombre>Angelica</nombre>
         <apellido>Peña</apellido>
         <fechanac>1898-06-08</fechanac>
         <sexo>Femenino</sexo>
      </alumno>
   </curso>
   <curso id="2">
      <name>Curso B</name>
      <alumno dni="E-81678249">
         <nombre>César</nombre>
         <apellido>Peña</apellido>
         <fechanac>1994-10-17</fechanac>
         <sexo>Masculino</sexo>
      </alumno>
      <alumno dni="E-16429342">
         <nombre>Marta</nombre>
         <apellido>De lucia</apellido>
         <fechanac>1984-01-23</fechanac>
         <sexo>Femenino</sexo>
      </alumno>
   </curso>
   <curso id="3">
      <name>Curso C</name>
      <alumno dni="V-17695342">
         <nombre>Omar</nombre>
         <apellido>Helguera</apellido>
         <fechanac>1987-08-23</fechanac>
         <sexo>Masculino</sexo>
      </alumno>
      <alumno dni="V-12685312">
         <nombre>Kimberli</nombre>
         <apellido>Di' Mario</apellido>
         <fechanac>1991-11-24</fechanac>
         <sexo>Femenino</sexo>
      </alumno>
   </curso> 
   <curso id="4">
      <name>Curso D</name>
      <alumno dni="E-18570232">
         <nombre>Inés</nombre>
         <apellido>Lopez</apellido>
         <fechanac>1992-03-30</fechanac>
         <sexo>Femenino</sexo>
      </alumno>
      <alumno dni="V-9345214">
         <nombre>Luis</nombre>
         <apellido>Mesa</apellido>
         <fechanac>1984-07-21</fechanac>
         <sexo>Masculino</sexo>
      </alumno>
   </curso>
</cursos>



simpleXML es una exención de PHP, fácil de usar, que nos permite parsear un XML de forma simple, convirtiéndolo en un objeto que pueda ser accedido con selectores normales y recorrido con iteraciones.

simpleXML requiere de PHP5 y libxml. Entre sus funciones mas importantes:


1.- simplexml_import_dom - obtiene un objeto SimpleXMLElement de un nodo DOM (lo contrario lo haríamos con la función dom_import_simplexml), ejemplo:
(clic para mostrar/ocultar el código)
// creamos la instancia
$XML = new DOMDocument;

// cargamos los nodos
$XML->loadXML
('
<cursos>
    <curso id="1">
      <name>Curso A</name>
      <alumno dni="V-6432123">
         <nombre>María</nombre>
         <apellido>Bolivar</apellido>
         <fechanac>1990-12-25</fechanac>
         <sexo>Femenino</sexo>
      </alumno>
      <alumno dni="V-9544321">
         <nombre>José</nombre>
         <apellido >García</apellido>
         <fechanac>1991-02-12</fechanac>
         <sexo>Masculino</sexo>
      </alumno>
   </curso>
</cursos>
');

// mostramos un mensaje en caso de error
if (!$XML) {
    echo 'Error analizando el documento';
    exit;
}

// convertimos el XML en un objeto
$obj = simplexml_import_dom($XML);

// mostrando un elemento cualquiera
echo $obj->curso[0]->alumno[0]->nombre;// devuelve maria
echo '<br/><hr/>';

// podemos acceder usando iteraciones
foreach ($obj->curso as $curso) { 
  echo $curso->name,'<br/>';
  foreach ($curso->alumno as $alumno) {
     echo $alumno->nombre,'<br/>';
     echo $alumno->apellido,'<br/>';
     echo $alumno->fechanac,'<br/>';
     echo $alumno->sexo,'<br/>';
     echo '--------------------------<br/>';
  }
}

/*
devuelve:
Curso A
  Marí­a
  Bolivar
  1990-12-25
  Femenino
  --------------------------
  José
  Garcí­a
  1991-02-12
  Masculino
--------------------------
*/


2.- simplexml_load_file - convierte un fichero XML en un objeto, ejemplo:
(clic para mostrar/ocultar)
// verificamos que exista el archivo
if (!file_exists('xml_ejemplo.xml')) {
   echo 'El fichero no existe!';exit;
}

// cargamos el XML
$cursos = simplexml_load_file('xml_ejemplo.xml');

// podemos acceder usando iteraciones
foreach ($cursos->curso as $curso) { 
  echo '*** <b>',$curso->name,'</b> *** <br/>';
  foreach ($curso->alumno as $alumno) {
     echo $alumno->nombre,'<br/>';
     echo $alumno->apellido,'<br/>';
     echo $alumno->fechanac,'<br/>';
     echo $alumno->sexo,'<br/>';
     echo '--------------------------<br/>';
  }
}

/*
devuelve:
*** Curso A ***
María
Bolivar
1990-12-25
Femenino
--------------------------
José
García
1991-02-12
Masculino
--------------------------
Angelica
Peña
1898-06-08
Femenino
--------------------------
*** Curso B ***
César
Peña
1994-10-17
Masculino

// y el resto ..

*/

Resolviendo un determinado caso - tenemos varios nodos llamados curso y queremos acceder solo a uno o todos los que aparezcan luego de él, una de las soluciones puede ser la siguiente:

a.- en nuestro XML de ejemplo cada etiqueta curso tiene un identificador (id) único <curso id="x">, de esa manera podemos seleccionar que nodos mostrar, usando una condición:
(clic para mostrar/ocultar)
foreach ($cursos->curso as $curso) {
  // mostramos solo los nodos mayores o iguales a 3
  if ($curso['id'] >= 3)// accedemos al atributo usando $objeto['atributo']
  {
     echo '*** <b>',$curso->name,'</b> *** <br/>';
     foreach ($curso->alumno as $alumno) {
        echo $alumno->nombre,'<br/>';
        echo $alumno->apellido,'<br/>';
        echo '--------------------------<br/>';
     }
  }
}

/*
devuelve:
*** Curso C ***
Omar
Helguera
--------------------------
Kimberli
Di' Mario
--------------------------
*** Curso D ***
Inés
Lopez
--------------------------
Luis
Mesa
--------------------------
*/

b.- accediendo solo a los nodos pares:
if ($curso['id'] % 2 == 0)

c.- accediendo a un determinado nodo:
if ($curso['id'] == 4) // nodo 4, Curso D
/* devuelve:
*** Curso D ***
Inés
Lopez
--------------------------
Luis
Mesa
--------------------------
*/

Ahora un ejemplo cargando el rss de cassianet y mostrando los titulos de las primeras cinco entradas:
(clic para mostrar/ocultar)
// cargamos el XML
$rss = @simplexml_load_file('http://feeds.feedburner.com/Cassianet?format=xml');

if (!is_object($rss)) {
   echo 'Error en el documento XML';exit;
} 

$i=0;
foreach ($rss->entry as $entrada) {
  if ($i==5) break;
  else $i++; 
  echo $i,' - ',$entrada->title ,'<br/>';

}

/* devuelve:
1 - Funciones de filtro en PHP
2 - Kiwi!
3 - Lightbox plugin de jQuery
4 - Google Code Prettify
5 - Blogger: iconos sociales flotantes
*/

esta vez usamos:
$obj = @simplexml_load_string($sXML);

if (!is_object($obj)) {
  echo 'Error en el documento XML';exit;
}

El símbolo @ antepuesto a la función indica que no deseamos que se muestre el error si lo hay, y para asegurarnos de que todo va bien, evaluamos si se creó el objeto antes de continuar "!is_object($obj))".


3.- simplexml_load_string retorna un objeto de tipo SimpleXMLElement a partir de una string. Si hay errores, retorna FALSE.
(clic para mostrar/ocultar)
// armamos el string
$sXML = '
<cursos>
    <curso id="1">
      <name>Curso A</name>
      <alumno dni="V-6432123">
         <nombre>María</nombre>
         <apellido>Bolivar</apellido>
         <fechanac>1990-12-25</fechanac>
         <sexo>Femenino</sexo>
      </alumno>
      <alumno dni="V-9544321">
         <nombre>José</nombre>
         <apellido >García</apellido>
         <fechanac>1991-02-12</fechanac>
         <sexo>Masculino</sexo>
      </alumno>
   </curso>
</cursos>';

// creamos el objeto
$obj = @simplexml_load_string($sXML);

if (!is_object($obj)) {
   echo 'Error en el documento XML';exit;
} 

// mostrando un elemento cualquiera
echo $obj->curso[0]->alumno[0]->nombre;// devuelve maria
echo '<br/><hr/>';

// podemos acceder usando iteraciones
foreach ($obj->curso as $curso) { 
  echo $curso->name,'<br/>';
  foreach ($curso->alumno as $alumno) {
     echo $alumno->nombre,'<br/>';
     echo $alumno->apellido,'<br/>';
     echo $alumno->fechanac,'<br/>';
     echo $alumno->sexo,'<br/>';
     echo '--------------------------<br/>';
  }
}


Consideraciones:

-si se nos presenta el caso de que tenemos nombre de etiquetas con guiones (ejemplo: fecha-nac), no podríamos acceder a su contenido usando:
echo $alumno->fecha-nac; // fecha de nacimiento

para ese caso tendríamos que hacerlo con llaves {} y entre comillas:
echo $alumno->{'fecha-nac'};


Son muchas las utilidades que podemos darle a esta extensión, se me ocurre por ejemplo, desarrollar un bot que cargue un RSS, los gestione y publique noticias externas (resúmenes o completas) en nuestro sitio.

Referencias:
php.net/SimpleXML

0 comentarios: Suscribete a los comentarios por RSS

Publicar un comentario

- Los comentarios están siendo moderados y serán publicados en la brevedad posible.