Wie bei Standard-Bibliothekscontainern hängt es von Ihren Anforderungen ab, welche Bibliothek Sie verwenden sollten. Hier ist ein praktisches Flussdiagramm:
Die erste Frage lautet also: Was brauchst du?
Ich benötige vollständige XML-Konformität
OK, Sie müssen also XML verarbeiten. Kein Spielzeug-XML, echtes XML. Sie müssen in der Lage sein, alle XML-Spezifikationen zu lesen und zu schreiben , nicht nur die tief liegenden, leicht zu analysierenden Bits. Sie benötigen Namespaces, DocTypes, Entity-Ersetzung, die Werke. Die W3C-XML-Spezifikation in ihrer Gesamtheit.
Die nächste Frage lautet: Muss Ihre API DOM oder SAX entsprechen?
Ich benötige eine genaue DOM- und / oder SAX-Konformität
OK, die API muss also wirklich DOM und / oder SAX sein. Es kann nicht nur ein Push-Parser im SAX-Stil oder ein beibehaltener Parser im DOM-Stil sein. Es muss das tatsächliche DOM oder das tatsächliche SAX sein, soweit C ++ dies zulässt.
Du hast gewählt:
Xerces
Das ist deine Entscheidung. Es ist so ziemlich der einzige C ++ - XML-Parser / -Schreiber, der die vollständige (oder so nahe wie C ++ zulässt) DOM- und SAX-Konformität aufweist. Es bietet außerdem XInclude-Unterstützung, XML-Schema-Unterstützung und eine Vielzahl weiterer Funktionen.
Es hat keine wirklichen Abhängigkeiten. Es verwendet die Apache-Lizenz.
DOM- und / oder SAX-Konformität sind mir egal
Du hast gewählt:
LibXML2
LibXML2 bietet eine C-artige Oberfläche (wenn Sie das wirklich stört, verwenden Sie Xerces), obwohl die Oberfläche zumindest etwas objektbasiert und einfach zu verpacken ist. Es bietet eine Vielzahl von Funktionen, wie XInclude - Unterstützung (mit Rückrufe so , dass man es kann sagen , wo es die Datei aus bekommt), einen XPath 1.0 Erkenner, RelaxNG und Schematron Unterstützung (obwohl die Fehlermeldungen einen lassen viel zu wünschen übrig), und so weiter.
Es hat zwar eine Abhängigkeit von iconv, kann jedoch ohne diese Abhängigkeit konfiguriert werden. Dies bedeutet jedoch, dass Sie nur eine begrenzte Anzahl möglicher Textcodierungen haben, die analysiert werden können.
Es verwendet die MIT-Lizenz.
Ich benötige keine vollständige XML-Konformität
OK, die vollständige XML-Konformität spielt für Sie keine Rolle. Ihre XML-Dokumente unterliegen entweder vollständig Ihrer Kontrolle oder verwenden garantiert die "grundlegende Teilmenge" von XML: keine Namespaces, Entitäten usw.
Was ist dir wichtig? Die nächste Frage lautet: Was ist für Sie das Wichtigste in Ihrer XML-Arbeit?
Maximale XML-Parsing-Leistung
Ihre Anwendung muss XML verwenden und es so schnell wie möglich in C ++ - Datenstrukturen umwandeln.
Du hast gewählt:
RapidXML
Dieser XML-Parser ist genau das, was er verspricht: Rapid XML. Es geht nicht einmal darum, die Datei in den Speicher zu ziehen. Wie das passiert, liegt bei Ihnen. Dabei wird das in eine Reihe von C ++ - Datenstrukturen analysiert, auf die Sie zugreifen können. Und das ungefähr so schnell, wie es dauert, um die Datei Byte für Byte zu scannen.
Natürlich gibt es kein kostenloses Mittagessen. Wie die meisten XML-Parser, die sich nicht für die XML-Spezifikation interessieren, berührt Rapid XML keine Namespaces, DocTypes, Entitäten (mit Ausnahme von Zeichenentitäten und den 6 grundlegenden XML-Entitäten) usw. Also im Grunde Knoten, Elemente, Attribute und so weiter.
Außerdem ist es ein Parser im DOM-Stil. Es ist also erforderlich, dass Sie den gesamten Text einlesen. Sie kopieren jedoch (normalerweise) keinen dieser Texte. Die Art und Weise RapidXML die meisten seine Geschwindigkeit wird durch Zeichenkette beziehen an Ort und Stelle . Dies erfordert mehr Speicherverwaltung von Ihrer Seite (Sie müssen diese Zeichenfolge am Leben erhalten, während RapidXML sie betrachtet).
Das DOM von RapidXML ist einfach. Sie können Zeichenfolgenwerte für Dinge erhalten. Sie können nach Attributen nach Namen suchen. Das ist alles. Es gibt keine praktischen Funktionen, um Attribute in andere Werte (Zahlen, Datumsangaben usw.) umzuwandeln. Sie bekommen nur Zeichenfolgen.
Ein weiterer Nachteil von RapidXML ist, dass das Schreiben von XML schmerzhaft ist . Es erfordert viel explizite Speicherzuweisung von Zeichenfolgennamen, um das DOM zu erstellen. Es bietet zwar eine Art Zeichenfolgenpuffer, erfordert jedoch noch viel explizite Arbeit. Es ist sicherlich funktionell, aber es ist ein Schmerz zu benutzen.
Es verwendet die MIT-Lizenz. Es ist eine reine Header-Bibliothek ohne Abhängigkeiten.
Leistung ist mir wichtig, aber nicht so sehr
Ja, Leistung ist Ihnen wichtig. Aber vielleicht brauchen Sie etwas weniger nacktes. Vielleicht etwas, das mehr Unicode verarbeiten kann oder nicht so viel benutzergesteuertes Speichermanagement erfordert. Leistung ist immer noch wichtig, aber Sie möchten etwas weniger direktes.
Du hast gewählt:
PugiXML
Historisch gesehen diente dies als Inspiration für RapidXML. Die beiden Projekte sind jedoch unterschiedlich, da Pugi mehr Funktionen bietet, während RapidXML sich ausschließlich auf die Geschwindigkeit konzentriert.
PugiXML bietet Unterstützung für die Unicode-Konvertierung. Wenn Sie also einige UTF-16-Dokumente haben und diese als UTF-8 lesen möchten, wird Pugi diese bereitstellen. Es hat sogar eine XPath 1.0-Implementierung, wenn Sie so etwas brauchen.
Aber Pugi ist immer noch ziemlich schnell. Wie RapidXML hat es keine Abhängigkeiten und wird unter der MIT-Lizenz vertrieben.
Riesige Dokumente lesen
Sie müssen Dokumente lesen, deren Größe in Gigabyte gemessen wird . Vielleicht bekommen Sie sie von stdin und werden von einem anderen Prozess gefüttert. Oder Sie lesen sie aus riesigen Dateien. Oder Wasauchimmer. Der Punkt ist, dass Sie nicht die gesamte Datei auf einmal in den Speicher lesen müssen, um sie zu verarbeiten.
Du hast gewählt:
LibXML2
Die SAX-API von Xerces funktioniert in dieser Funktion, aber LibXML2 ist hier, weil es etwas einfacher ist, damit zu arbeiten. Eine API im SAX-Stil ist eine Push-API: Sie beginnt mit dem Parsen eines Streams und löst nur Ereignisse aus, die Sie abfangen müssen. Sie sind gezwungen, Kontext, Status usw. zu verwalten. Code, der eine SAX-ähnliche API liest, ist viel weiter verbreitet, als man hoffen könnte.
Das xmlReader
Objekt von LibXML2 ist eine Pull-API. Sie fragen nach dem nächsten XML - Knoten oder Elemente zu gehen; es wird dir nicht gesagt. Auf diese Weise können Sie den Kontext nach Belieben speichern und verschiedene Entitäten auf eine Weise behandeln, die im Code viel besser lesbar ist als eine Reihe von Rückrufen.
Alternativen
Expat
Expat ist ein bekannter C ++ - Parser, der eine Pull-Parser-API verwendet. Es wurde von James Clark geschrieben.
Der aktuelle Status ist aktiv. Die neueste Version ist 2.2.9, die am (25.09.2019) veröffentlicht wurde.
LlamaXML
Es ist eine Implementierung einer StAX-API. Es ist ein Pull-Parser, ähnlich dem xmlReader
Parser von LibXML2 .
Aber es wurde seit 2005 nicht mehr aktualisiert. Also noch einmal, Caveat Emptor.
XPath-Unterstützung
XPath ist ein System zum Abfragen von Elementen in einem XML-Baum. Dies ist eine praktische Möglichkeit, ein Element oder eine Sammlung von Elementen mithilfe einer standardisierten Syntax effektiv nach allgemeinen Eigenschaften zu benennen. Viele XML-Bibliotheken bieten XPath-Unterstützung.
Hier gibt es effektiv drei Möglichkeiten:
- LibXML2 : Es bietet volle XPath 1.0-Unterstützung. Auch hier handelt es sich um eine C-API. Wenn Sie dies stört, gibt es Alternativen.
- PugiXML : Es wird auch XPath 1.0 unterstützt. Wie oben ist es eher eine C ++ - API als LibXML2, sodass Sie sich damit möglicherweise besser auskennen.
- TinyXML : XPath wird nicht unterstützt, aber es gibt die TinyXPath- Bibliothek, die es bereitstellt. TinyXML wird derzeit auf Version 2.0 konvertiert, wodurch sich die API erheblich ändert, sodass TinyXPath möglicherweise nicht mit der neuen API funktioniert. Wie TinyXML selbst wird TinyXPath unter der zLib-Lizenz vertrieben.
Erledige einfach den Job
Die XML-Korrektheit ist Ihnen also egal. Leistung ist für Sie kein Problem. Streaming ist irrelevant. Alles, was Sie wollen, ist etwas , das XML in den Speicher bringt und es Ihnen ermöglicht, es wieder auf die Festplatte zu kleben. Was Sie interessiert, ist API.
Sie möchten einen XML-Parser, der klein, einfach zu installieren, trivial zu verwenden und klein genug ist, um für die Größe Ihrer eventuellen ausführbaren Datei irrelevant zu sein.
Du hast gewählt:
TinyXML
Ich habe TinyXML in diesen Slot eingefügt, weil es ungefähr so einfach zu bedienen ist wie XML-Parser. Ja, es ist langsam, aber es ist einfach und offensichtlich. Es hat viele praktische Funktionen zum Konvertieren von Attributen und so weiter.
Das Schreiben von XML ist in TinyXML kein Problem. Sie stellen einfach new
einige Objekte zusammen, hängen sie zusammen, senden das Dokument an a std::ostream
, und alle sind glücklich.
Es gibt auch so etwas wie ein Ökosystem, das auf TinyXML basiert, mit einer iteratorfreundlicheren API und sogar einer darauf geschichteten XPath 1.0-Implementierung.
TinyXML verwendet die zLib-Lizenz, bei der es sich mehr oder weniger um die MIT-Lizenz mit einem anderen Namen handelt.