Extensiones XML

Hay varias formas de leer y escribir documentos XML en PHP, incluidas expresiones regulares y clases y métodos especializados. El enfoque regex es propenso a errores, especialmente con documentos XML complejos, por lo que se recomienda el uso de extensiones.
PHP proporciona varias extensiones para este propósito, las más comunes son las siguientes:

  • XMLWriter: esto nos permite generar flujos o archivos de datos XML
  • XMLReader: esto permite leer los datos XML
  • SimpleXML: convierte XML a un objeto y permite que un objeto se procese con selectores de propiedades normales e iteradores de matriz
  • DOM: esto nos permite operar en documentos XML a través de la API DOM

Los conceptos básicos para tratar con un documento XML son la lectura y escritura correcta de sus elementos y atributos. Asumamos el siguiente documento simple.xml:

<?xml version="1.0" encoding="UTF-8"?>
<customer>
<name type="string"><![CDATA[John]]></name>
<age type="integer">34</age>
<addresses>
<address><![CDATA[The Address #1]]></address>
<addresses>
</customer>

Usando XMLWriter, podemos crear el documento idéntico ejecutando el siguiente código:

<?php
$xml = new XMLWriter();
$xml->openMemory();
$xml->setIndent(true); // optional formatting
$xml->startDocument('1.0', 'UTF-8');
$xml->startElement('customer');
$xml->startElement('name');
$xml->writeAttribute('type', 'string');
$xml->writeCData('John');
$xml->endElement(); //
$xml->startElement('age');
$xml->writeAttribute('type', 'integer');
$xml->writeRaw(34);
$xml->endElement(); //
$xml->startElement('addresses');
$xml->startElement('address');
$xml->writeCData('The Address #1');
$xml->endElement(); //
$xml->endElement(); //
$xml->endElement(); //
$document = $xml->outputMemory();

Podemos ver que escribir el XML necesario fue una operación relativamente sencilla con XMLWriter. La extensión XMLWriter hace que nuestro código sea un poco difícil de leer al principio. Todos esos métodos startElement () y endElement () hacen que sea un poco tedioso descubrir dónde reside cada elemento en XML. Se necesita un poco de tiempo para acostumbrarse. Sin embargo, sí nos permite generar fácilmente documentos XML simples. Usando XMLReader, ahora podemos generar el Customer John, a los 34 años, que vive en la cadena The Address # 1 según los datos del documento XML dado usando el siguiente bloque de código:

<?php
$xml = new XMLReader();
$xml->open(__DIR__ . '/simple.xml');
$name = '';
$age = '';
$address = '';
while ($xml->read()) {
if ($xml->name == 'name') {
$name = $xml->readString();
$xml->next();
} elseif ($xml->name == 'age') {
$age = $xml->readString();
$xml->next();
} elseif ($xml->name == 'address') {
$address = $xml->readString();
$xml->next();
}
}
echo sprintf(
'Customer %s, at age %s, living at %s',
$name, $age, $address
);

Aunque el código en sí parece bastante simple, el ciclo while revela una naturaleza interesante de XMLReader. XMLReader lee el documento XML de arriba a abajo. Si bien este enfoque es una excelente opción para analizar de manera eficiente documentos XML grandes y complejos de una manera fluida, parece un poco exagerado para documentos XML más simples.
Veamos cómo SimpleXML maneja la escritura del mismo archivo simple.xml. El siguiente código genera casi el mismo contenido XML que XMLWriter:

<?php
$document = new SimpleXMLElement( '<?xml version="1.0" encoding="UTF-8" ?><customer></customer>' );
$name = $document->addChild('name', 'John');
$age = $document->addChild('age', 34);
$addresses = $document->addChild('addresses');
$address = $addresses->addChild('address', 'The Address #1');
echo $document->asXML();

La diferencia aquí es que no podemos pasar específicamente a nuestros elementos.
Existen soluciones alternativas que utilizan la función dom_import_simplexml (), pero esa es una función de la extensión DOM. No es que haya nada malo en ello, pero mantengamos nuestros ejemplos bien separados. Ahora que sabemos que podemos escribir documentos XML con SimpleXML, veamos cómo leerlos. Con SimpleXML, ahora podemos generar el mismo Cliente John, a los 34 años, que vive en la cadena The Address # 1 usando el siguiente código:

<?php
$document = new SimpleXMLElement(__DIR__ . '/simple.xml', null, true);
$name = (string)$document->name;
$age = (string)$document->age;
$address = (string)$document->addresses[0]->address;
echo sprintf(
'Customer %s, at age %s, living at %s',
$name, $age, $address
);

El proceso de lectura XML parece algo más corto con SimpleXML que con XMLReader, aunque ninguno de los ejemplos tiene ningún manejo de errores.
Echemos un vistazo al uso de la clase DOMDocument para escribir un documento XML:

<?php
$document = new DOMDocument('1.0', 'UTF-8');
$document->formatOutput = true; // optional
$customer = $document->createElement('customer');
$customer = $document->appendChild($customer);
$name = $document->createElement('name');
$name = $customer->appendChild($name);
$nameTypeAttr = $document->createAttribute('type');
$nameTypeAttr->value = 'string';
$name->appendChild($nameTypeAttr);
$name->appendChild($document->createCDATASection('John'));
$age = $document->createElement('age');
$age = $customer->appendChild($age);
$ageTypeAttr = $document->createAttribute('type');
$ageTypeAttr->value = 'integer';
$age->appendChild($ageTypeAttr);
$age->appendChild($document->createTextNode(34));
$addresses = $document->createElement('addresses');
$addresses = $customer->appendChild($addresses);
$address = $document->createElement('address');
$address = $addresses->appendChild($address);
$address->appendChild($document->createCDATASection('The Address #1'));
echo $document->saveXML();

Finalmente, veamos cómo DOMDocument maneja la lectura de documentos XML:

<?php
$document = new DOMDocument();
$document->load(__DIR__ . '/simple.xml');
$name = $document->getElementsByTagName('name')[0]->nodeValue;
$age = $document->getElementsByTagName('age')[0]->nodeValue;
$address = $document->getElementsByTagName('address')[0]->nodeValue;
echo sprintf(
'Customer %s, at age %s, living at %s',
$name, $age, $address
);

Las extensiones DOM y SimpleXMLElement hacen que sea bastante fácil leer los valores del documento XML, siempre y cuando tengamos confianza en la integridad de su estructura. Al tratar con documentos XML, debemos evaluar nuestro caso de uso en función de factores como el tamaño del documento. Si bien las clases XMLReader y XMLWriter son más detalladas, tienden a ser más eficientes cuando se usan correctamente.
Ahora que hemos obtenido una visión básica sobre cómo tratar con documentos XML en PHP, creemos nuestro primer servidor SOAP.

Comparte