J'ai toujours trouvé XML un peu lourd à traiter. Je ne parle pas d'implémenter un analyseur XML: je parle d' utiliser un analyseur basé sur un flux existant, comme un analyseur SAX, qui traite le nœud XML nœud par nœud.
Oui, il est vraiment facile d'apprendre les différentes API de ces analyseurs, mais chaque fois que je regarde du code qui traite XML, je le trouve toujours quelque peu compliqué. Le problème essentiel semble être qu'un document XML est logiquement séparé en nœuds individuels, et pourtant les types de données et les attributs sont souvent séparés des données réelles, parfois par plusieurs niveaux d'imbrication. Par conséquent, lors du traitement individuel d'un nœud particulier, de nombreux états supplémentaires doivent être maintenus pour déterminer où nous en sommes et ce que nous devons faire ensuite.
Par exemple, étant donné un extrait d'un document XML typique:
<book>
<title>Blah blah</title>
<author>Blah blah</author>
<price>15 USD</price>
</book>
... Comment pourrais-je déterminer quand j'ai rencontré un nœud de texte contenant un titre de livre? Supposons que nous ayons un analyseur XML simple qui agit comme un itérateur, nous donnant le nœud suivant dans le document XML chaque fois que nous appelons XMLParser.getNextNode()
. Je me retrouve inévitablement à écrire du code comme ceci:
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;
}
}
}
Fondamentalement, le traitement XML se transforme rapidement en une énorme boucle pilotée par une machine d'état, avec de nombreuses variables d'état utilisées pour indiquer les nœuds parents que nous avons trouvés plus tôt. Sinon, un objet de pile doit être conservé pour garder une trace de toutes les balises imbriquées. Cela devient rapidement sujet aux erreurs et difficile à maintenir.
Encore une fois, le problème semble être que les données qui nous intéressent ne sont pas directement associées à un nœud individuel. Bien sûr, cela pourrait être le cas si nous écrivions le XML comme:
<book title="Blah blah" author="blah blah" price="15 USD" />
... mais c'est rarement ainsi que XML est utilisé dans la réalité. Généralement, nous avons des nœuds de texte en tant qu'enfants des nœuds parents, et nous devons garder une trace des nœuds parents afin de déterminer à quoi un nœud de texte fait référence.
Alors ... je fais quelque chose de mal? Y a-t-il une meilleure façon? À quel moment l'utilisation d'un analyseur basé sur un flux XML devient-elle trop lourde, de sorte qu'un analyseur DOM à part entière devient nécessaire? J'aimerais entendre d'autres programmeurs sur le type d'idiomes qu'ils utilisent lors du traitement de XML avec des analyseurs basés sur des flux. L'analyse XML basée sur les flux doit-elle toujours devenir une énorme machine à états?