Eu sempre achei o XML um tanto complicado de processar. Não estou falando sobre a implementação de um analisador XML: estou falando sobre o uso de um analisador baseado em fluxo existente, como um analisador SAX, que processa o nó XML por nó.
Sim, é realmente fácil aprender as várias APIs para esses analisadores, mas sempre que olho para o código que processa XML, sempre acho que é um pouco complicado. O problema essencial parece ser que um documento XML é logicamente separado em nós individuais e, no entanto, os tipos e atributos de dados geralmente são separados dos dados reais, às vezes por vários níveis de aninhamento. Portanto, ao processar qualquer nó específico individualmente, é necessário manter muito estado extra para determinar onde estamos e o que precisamos fazer em seguida.
Por exemplo, dado um trecho de um documento XML típico:
<book>
<title>Blah blah</title>
<author>Blah blah</author>
<price>15 USD</price>
</book>
... Como determinaria quando encontrei um nó de texto contendo um título de livro? Suponha que tenhamos um analisador XML simples que age como um iterador, fornecendo o próximo nó no documento XML toda vez que chamamos XMLParser.getNextNode()
. Eu inevitavelmente me pego escrevendo código da seguinte maneira:
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;
}
}
}
Basicamente, o processamento XML rapidamente se transforma em um enorme loop controlado por máquina de estado, com muitas variáveis de estado usadas para indicar nós-pai que encontramos anteriormente. Caso contrário, um objeto de pilha precisa ser mantido para acompanhar todas as tags aninhadas. Isso rapidamente se torna propenso a erros e difícil de manter.
Novamente, o problema parece ser que os dados em que estamos interessados não estão diretamente associados a um nó individual. Claro, poderia ser, se escrevêssemos o XML como:
<book title="Blah blah" author="blah blah" price="15 USD" />
... mas raramente é assim que o XML é usado na realidade. Principalmente, temos nós de texto como filhos dos nós pais e precisamos acompanhar os nós pais para determinar a que um nó de texto se refere.
Então ... estou fazendo algo errado? Existe uma maneira melhor? Em que momento o uso de um analisador baseado em fluxo XML se torna muito complicado, para que um analisador DOM completo seja necessário? Eu gostaria de ouvir de outros programadores que tipo de idioma eles usam ao processar XML com analisadores baseados em fluxo. A análise XML baseada em fluxo deve sempre se transformar em uma enorme máquina de estado?