Ver Mensaje Individual
  #1 (permalink)  
Antiguo 28/03/2010, 14:56
Avatar de abimaelrc
abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 15 años
Puntos: 1517
[APORTE] Leer XML con SimpleXML y DOM

En este aporte nos concentraremos en cómo leer un archivo XML. Usaré de ejemplo el RSS de este foro. La dirección del RSS de este foro es http://www.forosdelweb.com/external....S2&forumids=18.

Vamos a ver dos librerías que nos ayudarán a leer el rss, estás son SimpleXML y DOM. El usar una o la otra va a depender de su simplicidad y/o control. SimpleXML tiene más restricciones que el DOM, pero SimpleXML es más fácil y va "directo al grano" (en ingles se dice "straitforward", no encontré una buena traducción para ese término) de lo que yo deseo ver.

Empezaremos usando la librería SimpleXML. Para obtener la información del RSS vamos a usar la función file_get_contents (para más información de como obtener los datos de una dirección externa puedes ver este aporte). De esta forma es como podemos obtener la información del RSS (para poder visualizar bien la estructura sugerimos, en este caso, que vea el código fuente):
Código PHP:
Ver original
  1. <?php
  2. header("Content-type: text/html; charset=utf-8");
  3. $rss_forosdelweb = file_get_contents("http://www.forosdelweb.com/external.php?type=RSS2&forumids=18");
  4. $xml = new SimpleXMLElement($rss_forosdelweb);
  5. var_dump($xml);
De esa forma podemos ver la estructura y los valores que tiene cada elemento. Una de las formas, que podemos manejar la información de cada uno de los elementos, es usando el método children.
Código PHP:
Ver original
  1. <?php
  2. header("Content-type: text/html; charset=utf-8");
  3. $rss_forosdelweb = file_get_contents("http://www.forosdelweb.com/external.php?type=RSS2&forumids=18");
  4. $xml = new SimpleXMLElement($rss_forosdelweb);
  5. foreach($xml->children() as $segunda_gen){
  6.     var_dump($segunda_gen);
  7.     //Para separar cada array y se pueda visualizar
  8.     echo str_pad("",20,PHP_EOL);
  9.     foreach($segunda_gen->children() as $tercera_gen){
  10.         var_dump($tercera_gen);
  11.         //Para separar cada array y se pueda visualizar
  12.         echo str_pad("",20,PHP_EOL);
  13.         foreach($tercera_gen->children() as $cuarta_gen){
  14.             var_dump($cuarta_gen);
  15.             //Para separar cada array y se pueda visualizar
  16.             echo str_pad("",20,PHP_EOL);
  17.         }
  18.     }
  19. }
  20.  
  21. /**
  22. * Adquirir la información con una función recursiva
  23. * Info de función recursiva -> http://campusvirtual.unex.es/cala/epistemowikia/index.php?title=Funci%C3%B3n_recursiva
  24. * Hace lo mismo que el ejemplo anterior
  25. */
  26. header("Content-type: text/html; charset=utf-8");
  27. $rss_forosdelweb = file_get_contents("http://www.forosdelweb.com/external.php?type=RSS2&forumids=18");
  28. $xml = new SimpleXMLElement($rss_forosdelweb);
  29. function recursiveFunc($rss){
  30.     foreach($rss->children() as $gen){
  31.         var_dump($gen);
  32.         if(count($gen->children()) > 0){
  33.             recursiveFunc($gen);
  34.             //Para separar cada array y se pueda visualizar
  35.             echo str_pad("",20,PHP_EOL);
  36.         }
  37.     }
  38. }
  39. recursiveFunc($xml);

Otra forma de poder ver los datos de un elemento es indicando la ruta directamente. La forma como podemos indicar la ruta es usando (->) en vez de indicarlo como un array ($foo["bar"]). El motivo es que te estás moviendo entre objetos. Ejemplo, si yo quisiera ver solamente los datos del elemento item
Código PHP:
Ver original
  1. <?php
  2. header("Content-type: text/html; charset=utf-8");
  3. $rss_forosdelweb = file_get_contents("http://www.forosdelweb.com/external.php?type=RSS2&forumids=18");
  4. $xml = new SimpleXMLElement($rss_forosdelweb);
  5. foreach($xml->channel->item as $item){
  6.     var_dump($item);
  7. }

Una vez ya sabemos lo que deseamos obtener, solo es necesario indicar las rutas de cada uno de los elementos que queremos. Por ejemplo, deseo mostrar el foro donde me encuentro y los datos a tomar son: el enlace del mensaje a leer, el título y la descripción.
Código PHP:
Ver original
  1. <?php
  2. header("Content-type: text/html; charset=utf-8");
  3. $rss_forosdelweb = file_get_contents("http://www.forosdelweb.com/external.php?type=RSS2&forumids=18");
  4. $xml = new SimpleXMLElement($rss_forosdelweb);
  5. echo "<span style='font-weight: bold; font-size: 26px;'>" . $xml->channel->title . "</span><br /><br />";
  6. foreach($xml->channel->item as $item){
  7.     echo "<a href='".$item->link."'>".$item->title."</a> -> " . nl2br(htmlentities($item->description, ENT_QUOTES, "UTF-8")) . "<br /><br />";
  8. }

Para poder obtener los datos de quién fue el que creo el mensaje y el avatar, tenemos que añadir unas líneas para poder mostrar la información de el Espacio de nombres (en ingles "namespaces"). Primero necesitamos obtener todas las direcciones de los "namespaces" y el método que nos ayudará es getNamespaces. Este método lo que hará es ingresar en alguna variable los atributos y las direcciones que requerimos para poder leer los "namespaces". Los prefijos de los "namespaces" en este rss son dc, content, media. Luego ingresamos la dirección en el método de children. Vamos a tomar el mismo código anterior y le queremos añadir de quién fue el mensaje y el avatar.
Código PHP:
Ver original
  1. <?php
  2. header("Content-type: text/html; charset=utf-8");
  3. $rss_forosdelweb = file_get_contents("http://www.forosdelweb.com/external.php?type=RSS2&forumids=18");
  4. $xml = new SimpleXMLElement($rss_forosdelweb);
  5. $getNS = $xml->getNamespaces(true);
  6. echo "<span style='font-weight: bold; font-size: 26px;'>" . $xml->channel->title . "</span><br /><br />";
  7. foreach($xml->channel->item as $item){
  8.     echo "<span style='color: #f00; font-weight: bold;'>" . $item->children($getNS["dc"])->creator . "</span> ";
  9.     //Verificamos que exista el nodo
  10.     if(count($item->children($getNS["media"])) > 0){
  11.         $avatar = $item->children($getNS["media"])->content;
  12.         echo "<img src='". $avatar->attributes()->url ."' alt='". $avatar->children($getNS["media"])->title ."' title='". $avatar->children($getNS["media"])->title ."' />";
  13.     }
  14.     echo " -><a href='".$item->link."'>".$item->title."</a> -> " . nl2br(htmlentities($item->description, ENT_QUOTES, "UTF-8")) . "<br /><br />";
  15. }
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos

Última edición por abimaelrc; 29/04/2010 a las 10:10