SimpleXML para PHP4

Simple XML para PHP4

De un tiempo a ésta parte el formato XML se ha vuelto imprescindible para implementar protocolos de intercambio de datos entre sistemas y lenguajes.

Todos los lenguajes incorporan parsers con los que poder leer y generar XMLs de una forma más o menos amena. Con la evolución de PHP a su versión 5 apareció una extensión llamada SimpleXML que, con un funcionamiento al estilo de objetos, simplificaba el acceso a los datos abandonando el método de llamadas a ciertas funciones al encontrar tags de apertura y cierre en el archivo XML.

Es una forma muy cómoda de trabajar es muy fácil acostumbrarse, pero a veces nos encontramos con hostings sólo en PHP 4 y nos vemos obligados a programar parsers a la vieja usanza.

Recientemente encontré una portabilidad de SimpleXML para PHP 4 que, aunque no dispone de absolutamente toda la funcionalidad de la extensión original (sobretodo al generar XML de salida), suple perfectamente la necesidad.

SimpleXML44 es el nombre de este backport de la extensión SimpleXML (escrito en PHP5) a PHP4. Según la web del autor, simplifica y optimiza el acceso a los datos y permite cambios en nodos CDATA y atributos, pero no es posible agregar o borrar ciertos nodos del árbol DOM. En mi toma de contacto (sólo lectura) cumplió perfectamente mis expectativas y ya lo tengo en mi biblioteca de paquetes de programación PHP.

Está escrito íntegramente en PHP. Requiere la versión de PHP 4.4.2 o superior y tener instalada la extensión XML Parser (Expat). La licencia es de tipo BSD. Actualmente forma parte del Ister PHP4 Framework aunque es posible descargarlo atómicamente, con lo que facilita nuestro desarrollo en nuestro propio framework.

Se puede descargar desde SourgeForge. La documentación del SimpleXML44 es algo limitada, pues se dan pocos ejemplos, pero habiendo usado el SimpleXML original nos hacemos una idea rápida de su funcionamiento.

Ejemplo de funcionamiento

Vamos a suponer un ejemplo rápido para ver lo simple que es. Pongamos que tenemos un archivo XML de la siguiente forma, guardado como ‘clientes.xml‘ en la raíz:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<clientes>
<cartera>50011</cartera>
<cliente id="101">
<nombre>Pepito</nombre>
<apellidos>Perez Garcia</apellidos>
<mail>[email protected]</mail>
</cliente>
<cliente id="201">
<nombre>Juan</nombre>
<apellidos>Apellido1 Apellido2</apellidos>
<mail>[email protected]</mail>
</cliente>
</clientes>

Pues bién, lo primero es descomprimir el archivo bajado en un directorio, donde queramos, por ejemplo en /simplexml44. En el script PHP pondremos lo siguiente:

//Incluimos el paquete SimpleXML44
require_once ‘simplexml44/IsterXmlSimpleXMLImpl.php’; //Creamos el objeto principal
$xml_object = new IsterXmlSimpleXMLImpl;

//Cargamos el documento a parsear
$doc = $xml_object->load_file(‘clientes.xml’);

//Printamos la cartera
print ‘Cartera: ‘.$doc->clientes->cartera->CDATA().'<br>’;

//Recorremos los clientes y printamos su info
foreach($doc->clientes->cliente as $cliente)
{
//Atributo ID
$atributos = $cliente->attributes();
print ‘ID: ‘.$atributos[‘id’].'<br>’;

//Campos
print ‘Nombre Completo: ‘.$cliente->nombre->CDATA().’ ‘.$cliente->apellidos->CDATA().'<br>’;
print ‘e-mail: ‘.$cliente->mail->CDATA().'<br>’;
}

Como vemos, es una forma de trabajar similar al SimpleXML original, muy sencilla e intuitiva.

Notas a tener en cuenta

  • Cada elemento hijo es un objeto.
  • Para extraer la información de un elemento se usa $elemento->CDATA(), aunque el campo no esté definido como CDATA.
  • Si un elemento tiene atributos, usando $elemento->attributes() obtenemos un array asociativo dónde la clave es el nombre del atributo y el valor es el valor del atributo.
  • Si un elemento está repetido (en nuestro caso el elemento ‘cliente’) en vez de un objeto se devuelve un array de objetos (en nuestro caso, un array de objetos ‘cliente’).
  • Si esperábamos un array de elementos pero sólo tenemos un sólo elemento, no se nos devuelve el array (lógico) y nuestro script puede fallar al esperar un array que no existe. La forma de manejarlo es mirando si es un array y si no lo es, poner el elemento dentro de un array:

    if(!is_array($doc->clientes->cliente)) $aux = array($doc->clientes->cliente);
    else $aux = $doc->clientes->cliente;

  • Si no es seguro que un elemento venga dado en el XML de origen, podemos preguntar si existe con isset():
    if(isset($doc->clientes->cartera)) …

Los errores que devuelve SimpleXML44

SimpleXML44 devuelve errores si los encuentra. Tanto si el archivo de entrada no existe, como si hay algun fallo en el XML, devuelve un error al estilo Warning que no es enviado al log, sino que se muestra por pantalla en una forma un tanto peculiar.

Si no encuentra el archivo muestra por pantalla la ruta dónde debería estar, sin más, algo cómo:

/ruta/al/archivo.xml

Si el código del script hacer referencia a un elemento que no existe y no lo hemos protegido con el isset() se quejará devolviendo un Fatal Error así:

Fatal error: Call to a member function on a non-object in /var/www/script.php on line xx

Si el XML no está bién formado devolverá un Warning propio al estilo:

WARNING isterxmlexpatnonvalid->parse(): expat: mismatched tag [217021/43/1846]

dónde los números entre los corchetes significan lo siguiente:

  • El primero: Posición del Byte dónde está el error
  • El segundo: Columna en el archivo XML donde está el error
  • El tercero: Línia en el archivo XML donde está el error

Conclusión

SimpleXML44 es una portabilidad a PHP4 que nos permite la comodidad de la extensión SimpleXML de PHP5. Algo limitada y sufrida con los errores, pero versátil y fácil de usar. Si debes portar una aplicación a PHP4 a causa de las limitaciones que el servidor dónde te hospedas, usas XML y estás acostumbrado al SimpleXML original, dále un vistazo que puede ser muy útil.

 

Vía: SyntaxError.es

Deja un comentario