Ich fand XML immer etwas umständlich zu verarbeiten. Ich spreche nicht über die Implementierung eines XML-Parsers: Ich spreche über die Verwendung eines vorhandenen Stream-basierten Parsers wie eines SAX-Parsers, der das XML Knoten für Knoten verarbeitet.
Ja, es ist wirklich einfach, die verschiedenen APIs für diese Parser zu lernen, aber wenn ich mir Code anschaue, der XML verarbeitet, finde ich ihn immer etwas kompliziert. Das wesentliche Problem scheint zu sein , dass ein XML - Dokument logisch in einzelne Knoten getrennt ist, und doch sind die Datentypen und Attribute werden oft von den tatsächlichen Daten, die manchmal durch mehrere Ebenen der Verschachtelung getrennt. Daher muss bei der individuellen Verarbeitung eines bestimmten Knotens viel zusätzlicher Status beibehalten werden, um zu bestimmen, wo wir uns befinden und was wir als Nächstes tun müssen.
Beispiel: Ein Ausschnitt aus einem typischen XML-Dokument:
<book>
<title>Blah blah</title>
<author>Blah blah</author>
<price>15 USD</price>
</book>
... Wie würde ich feststellen, wann ich auf einen Textknoten mit einem Buchtitel gestoßen bin? Angenommen, wir haben einen einfachen XML-Parser, der sich wie ein Iterator verhält und uns bei jedem Aufruf den nächsten Knoten im XML-Dokument gibt XMLParser.getNextNode()
. Ich schreibe unweigerlich Code wie den folgenden:
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;
}
}
}
Grundsätzlich wird die XML-Verarbeitung schnell zu einer riesigen, von der Zustandsmaschine gesteuerten Schleife, in der viele Statusvariablen verwendet werden, um übergeordnete Knoten anzuzeigen, die wir zuvor gefunden haben. Andernfalls muss ein Stapelobjekt verwaltet werden, um alle verschachtelten Tags zu verfolgen. Dies wird schnell fehleranfällig und schwierig zu warten.
Wieder scheint das Problem zu sein, dass die Daten, an denen wir interessiert sind, nicht direkt einem einzelnen Knoten zugeordnet sind. Sicher, es könnte sein, wenn wir das XML wie folgt schreiben:
<book title="Blah blah" author="blah blah" price="15 USD" />
... aber so wird XML in der Realität selten verwendet. Meistens haben wir Textknoten als untergeordnete Knoten von übergeordneten Knoten, und wir müssen die übergeordneten Knoten verfolgen, um zu bestimmen, worauf sich ein Textknoten bezieht.
Also ... mache ich etwas falsch? Gibt es einen besseren Weg? Ab wann wird die Verwendung eines XML-Stream-basierten Parsers zu umständlich, sodass ein vollwertiger DOM-Parser erforderlich wird? Ich würde gerne von anderen Programmierern hören, welche Art von Redewendungen sie bei der Verarbeitung von XML mit Stream-basierten Parsern verwenden. Muss Stream-basiertes XML-Parsing immer zu einer riesigen Zustandsmaschine werden?