¿Qué podemos hacer con XML y PHP ?

Quizás de primeras no seamos conscientes del potencial de estas dos tecnologías juntas, pero si nos fijamos bien, podemos darnos cuenta de que XML y PHP pueden funcionar de una forma muy similar a como puede trabajar PHP con una base de datos.
Aunque utilizar estas dos tecnologías juntas no excluye usar bases de datos, ¡eso es lo mejor de todo!.

En la segunda parte de este artículo veremos con juntar estas tres tecnologías para darle rienda suelta a nuestra imaginación.

Vamos al lío.

Para empezar vamos a crear nuestro archivo XML de ejemplo, al que llamaremos "noticias.xml" (por ser un poquito originales ;-) ):

<?xml version="1.0" encoding="ISO-8859-1"?>
<bloque>
<noticia>
<titulo>Hola Caracola </titulo>
<autor>KaoS</autor>
<cuerpo>Olla Kaitos a Luisete</cuerpo>
</noticia>
<noticia>
<titulo>Nuevo articulo en desarrolloweb </titulo>
<autor>Raul</autor>
<cuerpo>Jeje hola, aqui estamos </cuerpo>
</noticia>
</bloque>


Bueno ya tenemos creado nuestro archivo XML, que como ya sabemos nos permite crear nuestras propias etiquetas, aunque según en que estemos trabajando será recomendable seguir los estandarés establecidos por el w3c.

Ahora necesitamos crear un archivo PHP que lea nuestro archivo "noticias.xml".
¿Como podemos hacer esto? , pues es muy simple, porque PHP ya incluye ciertas funciones para el trabajo con archivos XML.Nosotros vamos a utilizar unas funciones que trabajan sobre PHP 4 ya que aún no todo el mundo tiene PHP 5 en su servidor, pero la forma de trabajar es muy similar. Dejo aquí una referencia de como trabajar del mismo modo pero usando las funciones de PHP 5.

Vamos a trabajar.

Lo primero que tenemos que hacer es leer el archivo, para ello utilizaremos nuestra queridísima función fopen. Da igual si el archivo se encuentra en nuestro servidor o no, por lo que si nos interesa podriamos crear un archivo PHP que funcionara igualmente en un servidor remoto que leyese las noticias de nuestra web.

//$ruta_fichero="http://www.dominio.com/noticias.xml";
$ruta_fichero="noticias.xml";

$contenido = "";
if($da = fopen($ruta_fichero,"r"))
{
while ($aux= fgets($da,1024))
{
$contenido.=$aux;
}
fclose($da);
}
else
{
echo "Error: no se ha podido leer el archivo <strong>$ruta_fichero</strong>";
}

Si todo ha ido correctamente ahora tendremos nuestro fichero XML cargado en nuestra variable $contenidoAhora un detalla, debido a que nuestras notícias podrían tener caracteres especiales, para evitar fallos le meteremos un pequeño filtro, que en este caso por ejemplo vamos a sustituir las tíldes y las eñes en el caso de que las hubiesen, para ello utilizaremos la función ereg_replace.

$contenido=ereg_replace("á","a",$contenido);
$contenido=ereg_replace("é","e",$contenido);
$contenido=ereg_replace("í","i",$contenido);
$contenido=ereg_replace("ó","o",$contenido);
$contenido=ereg_replace("ú","u",$contenido);
$contenido=ereg_replace("Á","A",$contenido);
$contenido=ereg_replace("É","E",$contenido);
$contenido=ereg_replace("Í","I",$contenido);
$contenido=ereg_replace("Ó","O",$contenido);
$contenido=ereg_replace("Ú","U",$contenido);
$contenido=ereg_replace("Ñ","NI",$contenido);
$contenido=ereg_replace("ñ","ni",$contenido);

El siguiente paso es cargar nuestro archivo XML en una estructura que podamos trabajar con PHP de forma comoda, para esta tarea vamos a utilizar las funciones dom que vienen implementadas a partir de la versión 4 de PHP. Concretamente usaremos:

  • domxml_open_mem : Crea un objeto DOM desde un documento XML
  • document_element : Crear un nuevo nodo de tipo elemento
  • get_elements_by_tagname: Obtiene elementos por el nombre de etiqueta
  • get_content : Obtiene el contenido del nodo

$tagnames = array ("titulo","autor","cuerpo");

if (!$xml = domxml_open_mem($contenido))
{
echo "Ha ocurrido un error al procesar el documento<strong> \"$ruta_fichero\"</strong> a XML <br>";
exit;
}
else
{
$raiz = $xml->document_element();

$tam=sizeof($tagnames);

for($i=0; $i<$tam; $i++)
{
$nodo = $raiz->get_elements_by_tagname($tagnames[$i]);
$j=0;
foreach ($nodo as $etiqueta)
{
$matriz[$j][$tagnames[$i]]=$etiqueta->get_content();
$j++;
}
}

Analicemos más detenidamente este último trozo de código a ver que es lo que realmente hace. Para empezar hemos creado un array con los campos que contiene cada noticia en la variable "tagnames". A continuación cargamos la variable contenido en un objeto DOM, en el caso de que todo haya ido bien extraemos el nodo raiz, en nuetro caso "bloque". El siguiente paso es calcular el numero de campos que obtendremos de cada noticia, para ello utilizamos la función sizeof que nos devuelve el tamaño del array.

Es ahora cuando extraemos la verdadera información del documento XML. Esta información la vamos a introducir en una matriz para que nos sea más simple trabajar con los datos. De forma que matriz quedase algo así:

indice \ Nombre Columnatituloautorcuerpo
0Hola CaracolaKaoSOlla Kaitos a Luisete
1Nuevo articulo en desarrollowebRaulJeje hola, aqui estamos

El primer bucle extrae las etiquetas de los nodos (primero titulo, despues autor y luego cuerpo).
El foreach se encarga de sacar una a una las etiquetas de cada una de las noticias, por lo que primero extrae "Hola Caracola" y en la segunda iteración "Nuevo articulo en desarrolloweb". De este modo vamos guardando en nuestra matriz los datos extraidos.

En la segunda iteración(repetición) del bucle for cogeremos la etiqueta autor, y en el foreach extraeremos los valores para introducirlos en nuetra matriz. Y así hasta terminar. ¡Lo mejor de todo es que de esto se encarga nuestro propio bucle!, nosotros solo tendremos que preocuparlos de declarar el array de etiquetas.

Bueno para que nos sea más comodo podemos crear una función a la que le pasaremos el archivo XML que queremos que nos lea y nos devuelva una matriz con los datos, haciendo así nuestro trabajo más limpio y eficiente. El código resultante sería:

function CargarXML($ruta_fichero)
{
$contenido = "";
if($da = fopen($ruta_fichero,"r"))
{
while ($aux= fgets($da,1024))
{
$contenido.=$aux;
}
fclose($da);
}
else
{
echo "Error: no se ha podido leer el archivo <strong>$ruta_fichero</strong>";
}

$contenido=ereg_replace("á","a",$contenido);
$contenido=ereg_replace("é","e",$contenido);
$contenido=ereg_replace("í","i",$contenido);
$contenido=ereg_replace("ó","o",$contenido);
$contenido=ereg_replace("ú","u",$contenido);
$contenido=ereg_replace("Á","A",$contenido);
$contenido=ereg_replace("É","E",$contenido);
$contenido=ereg_replace("Í","I",$contenido);
$contenido=ereg_replace("Ó","O",$contenido);
$contenido=ereg_replace("Ú","U",$contenido);
$contenido=ereg_replace("Ñ","NI",$contenido);
$contenido=ereg_replace("ñ","ni",$contenido);

$tagnames = array ("titulo","autor","cuerpo");

if (!$xml = domxml_open_mem($contenido))
{
echo "Ha ocurrido un error al procesar el documento<strong> \"$ruta_fichero\"</strong> a XML <br>";
exit;
}
else
{
$raiz = $xml->document_element();

$tam=sizeof($tagnames);

for($i=0; $i<$tam; $i++)
{
$nodo = $raiz->get_elements_by_tagname($tagnames[$i]);
$j=0;
foreach ($nodo as $etiqueta)
{
$matriz[$j][$tagnames[$i]]=$etiqueta->get_content();
$j++;
}
}

return $matriz;
}
}

Bueno, pues esto ya está casi todo listo, ya hemos cargado una matriz con el contenido de un archivo XML, por lo que ahora solo nos queda mostrar la información que queramos. Vamos a ver en un pequeño código como hacerlo.

$matriz=CargarXML("noticias.xml");

$num_noticias=sizeof($matriz);
for($i=0;$i<$num_noticias;$i++)
{
echo '
<table border=1>
<tr><td align=center>'.$matriz[$i]["titulo"].'</td></tr>
<tr><td>'.$matriz[$i]["cuerpo"].'</td></tr>
<tr><td align=right >'.$matriz[$i]["autor"].'</td></tr>
</table><br>
';
}


Voilà, ya tenemos nuestro primer ejemplo de XML+PHP. Aquí podeis ver el ejemplo funcionando:archivo xml y archivo xml formateado.
Bueno esto ha sido todo por hoy, espero que os haya sido de utilidad el artículo.

Autor

Raúl Jiménez Ortega

Desarrollador web

Compartir

Comentarios

Guillermo

06/6/2006
sino me equivoco el script anterior parace ser un poco seguro ya que se prodria incluir un archivo creado especialemente para el return $matris devuelva codigos PHP. Saludos.

Carlos

06/6/2006
Hay una manera bastante más eficaz de reemplazar las letras acentuadas, y otros caracteres. Se trata de codificar primero estas letras a caracteres especiales HTML ("&aacute;", "&ntilde", etc.), y entonces crear un patrón que busque la "&" como inicio, el ";" como final, y elimine todo lo que no sea el segundo carácter de la expresión. No incluyo aquí el listado pero con PHP es muy fácil.

Marcos

15/6/2006
No hay que olvidar habilitar en el archivo de inicio (PHP.INI) la biblioteca adecuada para el el manejo de XML, ya que por defecto NO esta habilitada. Esto se hace buscando en el PHP.INI, la linea "extension=php_domxml.dll"
y quitarle el puntoy coma.

Saludos

Salvador

08/7/2006
En el ejemplo creo que es más aconsejable utilizar

domxml_open_file

para leer un fichero xml

Más información sobre domxml_open_file
http://es2.php.net/manual/es/function.domxml-open-file.php

Martin

09/8/2006
Excelente artículo!
Un detalle. Para imprimir $matriz en algunos casos es conveniente hacerlo con utf8_decode . Al menos con el xml que he tenido que leer yo.

Saludos!

JaviBL

28/12/2006
Para solucionar el problema de las tildes y carácteres extraños.
- Tenemos que GUARDAR nuestro archivo xml a UTF-8 (con el mismo block de notas se puede hacer).
- Le ponemos la siguiente cabecera al XMl
<?xml version="1.0" encoding="UTF-8"?>
- En el archivo PHP, en el que vamos a mostrar los valores del XML escribimos
echo (utf8_decode($matriz[$i]["descripcion"]));
para decodificar el texto de las etiquetas del XML.

Un saludo

16/1/2007
Para el error de Allow url fopen. Yo tengo hosting en DreamHost y ellos no permiten abrir archivos externos. Existe un tutorial para resolverlo.
Les paso el link:
http://wiki.dreamhost.com/index.php/Allow_url_fopen
Y lo del DOMXML tenes que configurarlo desde php.ini. Yo lo hice asi y ahora anda de maravella.

Diego Armando Arias

18/5/2007
He configurado el php.ini pero me sigue sacando el siguiente error:
Fatal error: Call to undefined function domxml_open_file() in C:xampphtdocsxml_phpleerxml.php

Alguna sugerencia?

gracias

Vicente

05/6/2007
Yo tuve el mismo problema y encontré esta forma que creo que es mas rápida. Lo que no se si funciona el todos navegadores
http://www.w3schools.com/xml/tryit.asp?filename=cd_catalog_island_thead

juanromerocruz

06/7/2007
creo que hay un erro en el codigo, o por lo menos a mi no me funciona:


$matriz[$j][$tagnames[$i]]=$etiqueta->get_content();

creo que deberia ser

$matriz[$j][$i]=$etiqueta->get_content();

o al menos a mi asi es como me funciona, y si te pones a analizar el codigo se comprende por que

Un saludo a todos

Sommy

24/2/2009
Todos opinamos mucho, es cierto... En fin esta muy bueno el articulo.

Solo queria preguntar por que en lugar usas tantas lineas de mas con el ireg_replace, en lugar de usar la mitad de lineas con un str_ireplace?

Y lo que dicen arriba es mucho mas lio, las expresiones regulares no hay que abusarse de ellas, comen mucho.

Saludos!

Sommy

24/2/2009
Fe de erratas, es importante saber si el texto tiene mayusculas y respetarlas... Paso una funcion que arme que se basa en eso, pero con acutes.

Lo que si, no usen ereg_replace, es muy potente ya que utiliza expresiones regulares, utilicen str_replace(); Como decia mi primer tutor, es matar una hormiga con una bomba atomica, acostumbrense a optimizar recursos.

private function limpia_especiales($strCadena) {
$strCadenaOut=str_ireplace("á","&aacute;",$strCadena);
$strCadenaOut=str_ireplace("é","&eacute;",$strCadena);
$strCadenaOut=str_ireplace("í","&iacute;",$strCadena);
$strCadenaOut=str_ireplace("ó","&oacute;",$strCadena);
$strCadenaOut=strireplace("ú","&uacute;",$strCadena);
$strCadenaOut=str_ireplace("ñ","&ntilde;",$strCadena);
}

sommy

24/2/2009
Hacer las cosas apurado no es bueno, ni siquiera habia termiando la funcion, ahora si, no los molesto mas.

Suerte!

#-#############################################
# desc: Limpia una cadena y lo pasa a caracteres html, luego con Cdta[] no hay mas errores.
private function limpia_especiales($strCadena) {
$strCadenaOut=str_replace("á","&aacute;",$strCadena);
$strCadenaOut=str_replace("é","&eacute;",$strCadena);
$strCadenaOut=str_replace("í","&iacute;",$strCadena);
$strCadenaOut=str_replace("ó","&oacute;",$strCadena);
$strCadenaOut=str_replace("ú","&uacute;",$strCadena);
$strCadenaOut=str_replace("ñ","&ntilde;",$strCadena);
$strCadenaOut=str_replace("Á","&Aacute;",$strCadena);
$strCadenaOut=str_replace("É","&Eacute;",$strCadena);
$strCadenaOut=str_replace("Í","&Iacute;",$strCadena);
$strCadenaOut=str_replace("Ó","&Oacute;",$strCadena);
$strCadenaOut=str_replace("Ú","&Uacute;",$strCadena);
$strCadenaOut=str_replace("Ñ","&Ntilde;",$strCadena);

return $strCadenaOut;
}

Sommy

24/2/2009
Hola, les pido a los que revisen los mensajes que por favor editen y me pongan todo en uno... Los anteriores estan mal.

Para evitar funciones y replace solamente tienen que guardar el php que genera html como ANSI, no como UTF8, si usan flash agreguen en el primer frame esta linea:

System.useCodepage = true;

Listo!! Eviten Expresiones regulares y recursos, simplifiquen el codigo en recursos, no en lineas igual.

Saludos!

Guillermo Flores

30/5/2009
Problemas con XMML
Que tal...

estoy haciendo pruebas con los ejemplo que aqui indicas pero sucede algo bien raro, la pagina del php no me esta imprimiendo nada en el browser, es decir, la pagina se muestra en blanco.

Habra algo que modificar en el php.ini??? o por donde podria estar mi problmea?

Agradezco enormemente su aportacion.

agrana

06/8/2009
Como Trabajar con DOM/XML
Saludos Amigos...

Me Costo un mundo poder ver como trabaja DOM XML de PHP de 5 en adelante ...
1.- Las librerias en las versiones PHP de 5 en adelante esta complidas es decir ya no es una extension..
2.- Por Otra parte el codigo que voy a facilitar va enviar lo siguiente a una archivo
<?xml version="1.0" encoding="UTF-8"?>
<rows>
<row id="1">
<cell>Grupo No.1</cell>
<cell>GRUPO UNO</cell>
</row>
<row id="2">
<cell>Grupo No.2</cell>
<cell>MARCOS</cell>
</row>
<row id="3">
<cell>Grupo No.3</cell>
<cell>POPEYE</cell>
</row>
</rows>
PUEDEN NOTAR QUE EL XML va dentro de otras etiquetas es decir ROWS (Indice Principal) ROW (los Sudindices) y CELL (las Celdas)... De la misma Manera vamos a tratar el codigo en PHP.... y aqui va el codigo...

$doc = new DOMDocument ( '1.0', 'UTF-8' ); /// Abrimos el DOMXML Documento

$element = $doc->appendChild(new DOMElement('rows')); // Creamos el Indice Principal ROWS

$i=1;
$resultj = mysql_query("SELECT * FROM _tgrupo order by IDG"); // Una Simple Intruccion SQL para mostrar un el ejemplo
while($Row = mysql_fetch_array($resultj))
{

// Esto es muy Importante Fijense Bien $element fue la misma variable para llamar la Instruccion en el INDICE ROWS en otras palabras estamos indicando que este nuevo elemento pertenece al INDICE ROWS..

$element1 = $element->appendChild(new DOMElement('row'));
$element1->setAttribute("id", $i); /// Para asiganar el atributo ID

// Aqui pasa lo mismo si ven los apuntadores ahora llaman a $element1 para que ellos pertenezcan al SUBINDICE ROW, en este caso ahora a dos etiquetas llamadas CELL

$element_ns = new DOMElement('cell', 'Grupo No.'.$Row['IDG'], '');
$element1->appendChild($element_ns);
$element_ns = new DOMElement('cell', $Row['Descrip'], '');
$element1->appendChild($element_ns);

$i++;

}
$doc->save("grid.xml"); /// <== Aqui lo grabamos a un archivo .XML


Si tiene alguna duda escriban a mi correo.. creo que la explicacion de este articulo esta bien pero es hacer las cosas casi a mano.. y no es la idea PHP es muy poderoso para hacer un archivo tan escueto...

mi correo:angelgranadillo@yahoo.com

Espero que le sirva de mucho

Narucho

11/10/2009
Tengo problema al crear el xml
Hola mucho gusto pues yo use un codigo similar y al final use:
$doc->save("test.xml");

pero en mi localhost no me crea el archivo, ya revise los permisos en mi iis ver. 5, con php 5.2.11. He leido otros artuculos y aun no doy con el problema, ya que ese mismo codigo subido en mi host funciona.

cristhian

09/3/2010
agregen este libreria domxml-php4-to-php5
esta libreria
he incluyenla en el archivo

dir :
http://alexandre.alapetite.fr/doc-alex/domxml-php4-php5/index.en.html

el articulo esta perfecto y me funciono ya que las funciones llamadas dan errror domxml_open_mem()
hagan el include y perfecto..

david

10/7/2010
Excelente Articulo.
Gracias por el aporte. Fácilmente pude configurar lo a mis necesidades.

jose

20/11/2010
diseñar con xml y php
quiero aprender a diseñar con php

djkaizen

23/11/2010
Resolver Fatal error: Call to undefined function: dom_xml_open_mem()
Cuando desee ejecutar el archivo para leer el XML me salio el error

Fatal error:Call to undefined function: dom_xml_open_mem()

Después de ver varios artículos que no me fueron muy útiles decidí buscar internamente el error, la solución si trabajas con Wamp es esta:

Detener los servicios de Wamp.
Clic sobre el icono WAMP>>PHP>>PHP Extensions>>
Activar la extensión php_domxml
Reiniciar WAMP y listo.

(No necesité configurar el PHP.ini)

Martin

03/1/2011
MEJOR SOLUCION A LOS CARACTERES ESPECIALES
La mejor solución a los caracteres especiales es simplemente imprimir asi el contenido: echo utf8_encode($contenido);

Saludos !

huchiman

15/2/2011
php 5.2.14
Bueno, espero le sirva a alguien, estoy empezando a probar y pude quitar el mensaje de error de "Call to undefined function domxml_open_mem" con mi php 5.2.14 encontré este articulo http://alexandre.alapetite.fr/doc-alex/domxml-php4-php5/index.en.html
el truco fué
if (PHP_VERSION>='5')
require_once('domxml-php4-to-php5.php');
en la liga está el archivo, se coloca junto a los demas y listo.

Saludos

Freddy

14/6/2011
no me reconoce el archivo php_domxml.dll
Que tal a todos, estoy comenzando con esto de los archivos .xml. Favor necesito de su ayuda.

Al ejecutar me aparece el error que no me reconoce el archivo php_domxml.dll:

1.- Lo descomente en el php.ini y el php.ini en el de la ruta que me muestra el phpinfo()
2.- El archivo si existe en la carpeta extensions.
3.- La carpeta extensions está bien ruteada en el php.ini.
4.- Incluso realicé reset al servidor.

necesito ayuda urgente.

Saludos y gracias

fsoto

15/6/2011
No encuentra archivo php_domxml.dll
Ayuda para leer archivo .xml.

Al ejecutar aparece el error que no encuentra el archivo php_domxml.dll, por lo tanto tampoco me reconoce la función domxml_open_mem():

1.- Está descomentado en el php.ini y el php.ini es el de la ruta que me muestra el phpinfo()
2.- El archivo php_domxml.dll si existe en la carpeta extensions.
3.- La carpeta extensions que contiene el archivo php_domxml.dll está bien ruteada en el php.ini.
4.- Incluso realicé reset al servidor.

necesito ayuda urgente.

Saludos y gracias

Ricardo

11/3/2013
Otra forma de utilizar XML y PHP
Otra forma eficiente de utilizar XML y PHP es la separación del desarrollo en dos capas, una capa de presentación (XSL) y otra de negocio (o programa php). El diseño de la pagina se realizar en formato XSL que incluye marcas (TAGS) que hacen referencias a los datos XML y, el programa PHP genera un string con datos en formato XML (texto que puede ser leido de un archivo o creado a partir de datos de una base de datos). Posteriormente, mediante la función transformToXML() de PHP, se funcionan los datos del string XML con la plantilla XSL generando código HTML. Desarrollar de esta forma significa un cambio importante en la forma de programar con PHP.