Siempre he encontrado que XML es algo engorroso de procesar. No estoy hablando de implementar un analizador XML: estoy hablando de usar un analizador basado en flujo existente, como un analizador SAX, que procesa el nodo XML por nodo.
Sí, es realmente fácil aprender las diversas API para estos analizadores, pero cada vez que miro el código que procesa XML siempre encuentro que es algo complicado. El problema esencial parece ser que un documento XML está separado lógicamente en nodos individuales y, sin embargo, los tipos y atributos de datos a menudo están separados de los datos reales, a veces por múltiples niveles de anidamiento. Por lo tanto, cuando se procesa un nodo en particular individualmente, se debe mantener una gran cantidad de estado adicional para determinar dónde estamos y qué debemos hacer a continuación.
Por ejemplo, dado un fragmento de un documento XML típico:
<book>
<title>Blah blah</title>
<author>Blah blah</author>
<price>15 USD</price>
</book>
... ¿Cómo determinaría cuándo me encuentro con un nodo de texto que contiene el título de un libro? Supongamos que tenemos un analizador XML simple que actúa como un iterador, dándonos el siguiente nodo en el documento XML cada vez que llamamos XMLParser.getNextNode()
. Inevitablemente me encuentro escribiendo código como el siguiente:
boolean insideBookNode = false;
boolean insideTitleNode = false;
while (!XMLParser.finished())
{
....
XMLNode n = XMLParser.getNextNode();
if (n.type() == XMLTextNode)
{
if (insideBookNode && insideTitleNode)
{
// We have a book title, so do something with it
}
}
else
{
if (n.type() == XMLStartTag)
{
if (n.name().equals("book")) insideBookNode = true
else if (n.name().equals("title")) insideTitleNode = true;
}
else if (n.type() == XMLEndTag)
{
if (n.name().equals("book")) insideBookNode = false;
else if (n.name().equals("title")) insideTitleNode = false;
}
}
}
Básicamente, el procesamiento XML se convierte rápidamente en un gran bucle controlado por máquinas de estado, con muchas variables de estado utilizadas para indicar nodos principales que hemos encontrado anteriormente. De lo contrario, se debe mantener un objeto de pila para realizar un seguimiento de todas las etiquetas anidadas. Esto rápidamente se vuelve propenso a errores y difícil de mantener.
Nuevamente, el problema parece ser que los datos que nos interesan no están directamente asociados con un nodo individual. Claro, podría ser, si escribiéramos el XML como:
<book title="Blah blah" author="blah blah" price="15 USD" />
... pero así es como se usa XML en la realidad. La mayoría de las veces tenemos nodos de texto como hijos de nodos principales, y necesitamos hacer un seguimiento de los nodos principales para determinar a qué se refiere un nodo de texto.
Entonces ... ¿estoy haciendo algo mal? ¿Hay una mejor manera? ¿En qué punto el uso de un analizador basado en flujo XML se vuelve demasiado engorroso, por lo que se hace necesario un analizador DOM completo? Me gustaría saber de otros programadores qué tipo de modismos usan cuando procesan XML con analizadores basados en secuencias. ¿El análisis XML basado en secuencias debe convertirse siempre en una gran máquina de estados?