Ver Mensaje Individual
  #2 (permalink)  
Antiguo 28/03/2010, 14:57
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, 6 meses
Puntos: 1517
Respuesta: [APORTE] Leer XML con SimpleXML y DOM

Para poder acceder a un documento XML con la librería DOM, lo necesitamos hacer de esta forma
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. $xmlDOM = new DOMDocument();
  5. $xmlDOM->loadXML($rss_forosdelweb);
  6. var_dump($xmlDOM->saveXML());

Primero hemos almacenado la información del RSS en la variable $rss_forosdelweb usando la función file_get_contents. Creamos el objeto de DOMDocument y cargamos al objeto la información almacenada en la variable $rss_forosdelweb. Para mostrar la información en pantalla usamos el método saveXML. Si deseamos movernos en cada uno de los elementos podemos usar la propiedad childNodes. Estaremos usando en este aporte las propiedas nodeType, nodeName, nodeValue, childNodes, firstChild, lastChild, nextSibling, previusSibling, parentNode, documentElement y attributes.
  • nodeType = Verificar cual es el tipo de nodo. El valor que publica esta variable es un número entero, y representa una constante predefinida.
  • nodeName = Indica el nombre del nodo.
  • nodeValue = Nos ofrece acceder a ciertos contenidos en los nodos. Nos permite ver atributos, secciones de CDATA, comentarios y texto.
  • childNodes = Nos permite acceder a los nodos que son descendientes directos del nodo en que nos encontremos.
  • firstChild = Nos permite acceder al primer descendiente directo del nodo en que nos encontramos.
  • lastChild = Nos permite acceder al último descendiente directo del nodo en que nos encontramos.
  • nextSibling = Nos permite acceder al siguiente elemento que está en el nodo donde nos encontramos.
  • previusSibling = Nos permite acceder al elemento anterior que está en el nodo donde nos encontramos.
  • parentNode = Nos permite acceder al nodo ascendiente directo del nodo en que nos encontramos.
  • documentElement = Es más bien una forma de enfocarnos en el cuerpo de los elementos. Sin él, nos traerá también información del primer elemento, que en este caso es <rss...>
  • attributes = Nos da la información de los atributos en un elemento.

Para poder acceder a cada uno de los elementos, podemos lograrlo de esta forma:
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. $xmlDOM = new DOMDocument();
  5. $xmlDOM->loadXML($rss_forosdelweb);
  6. $documentElement = $xmlDOM->documentElement;
  7. foreach($documentElement->childNodes as $primera_gen){
  8.     if($primera_gen->nodeType != XML_TEXT_NODE){
  9.         echo $primera_gen->nodeName;
  10.         if($primera_gen->hasAttributes()){
  11.             foreach($primera_gen->attributes as $attr){
  12.                 echo " [" . $attr->nodeName . "]";
  13.             }
  14.         }
  15.         echo "\n";
  16.         foreach($primera_gen->childNodes as $segunda_gen){
  17.             if($segunda_gen->nodeType != XML_TEXT_NODE){
  18.                 echo "\t" . $segunda_gen->nodeName;
  19.                 if($segunda_gen->hasAttributes()){
  20.                     foreach($segunda_gen->attributes as $attr){
  21.                         echo " [" . $attr->nodeName . "]";
  22.                     }
  23.                 }
  24.                 echo "\n";
  25.                 foreach($segunda_gen->childNodes as $tercera_gen){
  26.                     if($tercera_gen->nodeType != XML_TEXT_NODE){
  27.                         echo "\t\t" . $tercera_gen->nodeName;
  28.                         if($tercera_gen->hasAttributes()){
  29.                             foreach($tercera_gen->attributes as $attr){
  30.                                 echo " [" . $attr->nodeName . "]";
  31.                             }
  32.                         }
  33.                         echo "\n";
  34.                         foreach($tercera_gen->childNodes as $cuarta_gen){
  35.                             if($cuarta_gen->nodeType != XML_TEXT_NODE){
  36.                                 echo "\t\t\t" . $cuarta_gen->nodeName;
  37.                                 if($cuarta_gen->hasAttributes()){
  38.                                     foreach($cuarta_gen->attributes as $attr){
  39.                                         echo " [" . $attr->nodeName . "]";
  40.                                     }
  41.                                 }
  42.                                 echo "\n";
  43.                                 if($cuarta_gen->firstChild->nextSibling->nodeType == XML_ELEMENT_NODE){
  44.                                     foreach($cuarta_gen->childNodes as $quinta_gen){
  45.                                         if($quinta_gen->nodeType != XML_TEXT_NODE){
  46.                                             echo "\t\t\t\t" . $quinta_gen->nodeName;
  47.                                             if($quita_gen->hasAttributes()){
  48.                                                 foreach($quita_gen->attributes as $attr){
  49.                                                     echo " [" . $attr->nodeName . "]";
  50.                                                 }
  51.                                             }
  52.                                             echo "\n";
  53.                                         }
  54.                                     }
  55.                                 }
  56.                             }
  57.                         }
  58.                     }
  59.                 }
  60.             }
  61.         }
  62.     }
  63. }
  64.  
  65. /**
  66. * Adquirir la información con una función recursiva
  67. * Info de función recursiva -> http://campusvirtual.unex.es/cala/epistemowikia/index.php?title=Funci%C3%B3n_recursiva
  68. * Hace lo mismo que el ejemplo anterior
  69. */
  70. header("Content-type: text/html; charset=utf-8");
  71. $rss_forosdelweb = file_get_contents("http://www.forosdelweb.com/external.php?type=RSS2&forumids=18");
  72. $xmlDOM = new DOMDocument();
  73. $xmlDOM->loadXML($rss_forosdelweb);
  74. $documentElement = $xmlDOM->documentElement;
  75. /**
  76. * Función para mostrar tabulado los elementos.
  77. */
  78. function addTab($v,$n){
  79.     if($v->firstChild->nextSibling->nodeType == XML_ELEMENT_NODE || $v->firstChild->nodeType == XML_CDATA_SECTION_NODE){
  80.         return ++$n;
  81.     }
  82. }
  83. function searchElements($value, $n=0){
  84.     foreach($value->childNodes as $gen){
  85.         if($gen->nodeType != XML_TEXT_NODE){
  86.             echo str_pad("", $n, "\t") . $gen->nodeName;
  87.             if($gen->hasAttributes()){
  88.                 foreach($gen->attributes as $attr){
  89.                     echo " [" . $attr->nodeName . "]";
  90.                 }
  91.             }
  92.             echo "\n";
  93.             if($gen->firstChild->nextSibling->nodeType == XML_ELEMENT_NODE || $gen->firstChild->nodeType == XML_CDATA_SECTION_NODE){
  94.                 searchElements($gen, addTab($gen,$n));
  95.             }
  96.         }
  97.     }
  98. }
  99. searchElements($documentElement);

Para poder acceder a los atributos, hemos primero verificado que existan usando el método hasAttributes y si hay atributos, los mostramos con la propiedad attributes.

Hemos estado verificando, antes del foreach, si el próximo nodo es del tipo Texto o no, para poder continuar con el foreach (si no da un "Warning", para mayor detalle de los errores ver este aporte). El motivo de estos Textos es que se crea un espacio entre cada elemento. Cuando el DOM verifica el próximo nodo, encuentra que el próximo elemento es del tipo Texto. Si los elementos se encuentre juntos no aparece el tipo texto. Esto se puede lograr haciendo un preg_replace y remplazando los espacios que hay entre cada elemento. No es lo recomendable, ya que en este caso, se usan secciones de CDATA y estos contienen información en formato de HTML. Cuando el preg_replace una los elementos, también afectará los que haya encontrado en el CDATA. Ejemplo de uso
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. $rss_forosdelweb = preg_replace("/\s*(<[^>]*>)\s*/","$1",$rss_forosdelweb);
  5. $xmlDOM = new DOMDocument();
  6. $xmlDOM->loadXML($rss_forosdelweb);
  7. $documentElement = $xmlDOM->documentElement;
  8. /**
  9. * Función para mostrar tabulado los elementos.
  10. */
  11. function addTab($v,$n){
  12.     if($v->firstChild->nextSibling->nodeType == XML_ELEMENT_NODE || $v->firstChild->nodeType == XML_CDATA_SECTION_NODE){
  13.         return ++$n;
  14.     }
  15. }
  16. function searchElements($value, $n=0){
  17.     foreach($value->childNodes as $gen){
  18.         if($gen->nodeType != XML_TEXT_NODE){
  19.             echo str_pad("", $n, "\t") . $gen->nodeName;
  20.             if($gen->hasAttributes()){
  21.                 foreach($gen->attributes as $attr){
  22.                     echo " [" . $attr->nodeName . "]";
  23.                 }
  24.             }
  25.             echo "\n";
  26.             if($gen->firstChild->nextSibling->nodeType == XML_ELEMENT_NODE || $gen->firstChild->nodeType == XML_CDATA_SECTION_NODE){
  27.                 searchElements($gen, addTab($gen,$n));
  28.             }
  29.         }
  30.     }
  31. }
  32. searchElements($documentElement);
__________________
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; 26/05/2010 a las 09:37