Proprio come con i contenitori di librerie standard, quale libreria si dovrebbe usare dipende dalle proprie esigenze. Ecco un diagramma di flusso conveniente:
Quindi la prima domanda è questa: di cosa hai bisogno?
Ho bisogno della piena conformità XML
OK, quindi è necessario elaborare XML. Non un giocattolo XML, un vero XML. Devi essere in grado di leggere e scrivere tutte le specifiche XML, non solo i bit bassi e facili da analizzare. Hai bisogno di spazi dei nomi, DocTypes, sostituzione delle entità, opere. La specifica XML del W3C, nella sua interezza.
La domanda successiva è: l'API deve essere conforme a DOM o SAX?
Ho bisogno di conformità esatta DOM e / o SAX
OK, quindi hai davvero bisogno che l'API sia DOM e / o SAX. Non può essere solo un parser push in stile SAX o un parser mantenuto in stile DOM. Essa deve essere DOM reale o il SAX reale, nella misura in cui C ++ consente.
Tu hai scelto:
Xerces
Questa e 'la tua scelta. È praticamente l'unico parser / writer XML C ++ che ha piena (o quasi quanto C ++ consente) conformità DOM e SAX. Ha anche il supporto XInclude, il supporto XML Schema e una pletora di altre funzionalità.
Non ha dipendenze reali. Utilizza la licenza Apache.
Non mi interessa la conformità DOM e / o SAX
Tu hai scelto:
libxml2
LibXML2 offre un'interfaccia in stile C (se questo ti disturba davvero, usa Xerces), sebbene l'interfaccia sia almeno un po 'basata sugli oggetti e facilmente racchiusa. Fornisce molte funzionalità, come il supporto XInclude (con callback in modo da poterlo dire da dove ottiene il file), un riconoscitore XPath 1.0, supporto RelaxNG e Schematron (anche se i messaggi di errore lasciano molto a desiderare), e così via.
Ha una dipendenza da iconv, ma può essere configurato senza quella dipendenza. Ciò significa che avrai un set più limitato di possibili codifiche di testo che può analizzare.
Utilizza la licenza MIT.
Non ho bisogno della piena conformità XML
OK, quindi la piena conformità XML non conta per te. I tuoi documenti XML sono completamente sotto il tuo controllo o sono garantiti per utilizzare il "sottoinsieme di base" di XML: nessuno spazio dei nomi, entità, ecc.
Quindi cosa ti importa? La domanda successiva è: qual è la cosa più importante per te nel tuo lavoro XML?
Prestazioni massime di analisi XML
La tua applicazione deve prendere XML e trasformarlo in strutture di dati C ++ il più rapidamente possibile.
Tu hai scelto:
RapidXML
Questo parser XML è esattamente ciò che dice sulla confezione: XML rapido. Non si occupa nemmeno di estrarre il file in memoria; come succede dipende da te. Ciò di cui si occupa è analizzarlo in una serie di strutture di dati C ++ a cui è possibile accedere. E lo fa con la stessa velocità necessaria per scansionare il file byte per byte.
Certo, non esiste un pranzo gratis. Come la maggior parte dei parser XML che non si preoccupano delle specifiche XML, Rapid XML non tocca spazi dei nomi, DocTypes, entità (ad eccezione delle entità carattere e delle 6 XML di base) e così via. Quindi fondamentalmente nodi, elementi, attributi e simili.
Inoltre, è un parser in stile DOM. Quindi richiede di leggere tutto il testo. Tuttavia, ciò che non fa è copiare qualsiasi di quel testo (di solito). Il modo in cui RapidXML ottiene la massima velocità è facendo riferimento alle stringhe sul posto . Ciò richiede una maggiore gestione della memoria da parte dell'utente (è necessario mantenere viva quella stringa mentre RapidXML la sta guardando).
Il DOM di RapidXML è bare-bones. Puoi ottenere valori stringa per cose. Puoi cercare gli attributi per nome. Questo è tutto. Non ci sono funzioni utili per trasformare gli attributi in altri valori (numeri, date, ecc.). Ottieni solo stringhe.
Un altro aspetto negativo di RapidXML è che è doloroso scrivere XML. Richiede molta allocazione di memoria esplicita dei nomi delle stringhe per costruire il suo DOM. Fornisce una sorta di buffer di stringhe, ma ciò richiede ancora molto lavoro esplicito da parte tua. È certamente funzionale, ma è un dolore da usare.
Utilizza la licenza MIT. È una libreria di sola intestazione senza dipendenze.
Mi preoccupo delle prestazioni ma non abbastanza
Sì, le prestazioni contano per te. Ma forse hai bisogno di qualcosa di meno ossa nude. Forse qualcosa che può gestire più Unicode o che non richiede così tanta gestione della memoria controllata dall'utente. Le prestazioni sono ancora importanti, ma vuoi qualcosa di un po 'meno diretto.
Tu hai scelto:
PugiXML
Storicamente, ciò ha ispirato RapidXML. Ma i due progetti sono divergenti, con Pugi che offre più funzionalità, mentre RapidXML si concentra interamente sulla velocità.
PugiXML offre il supporto per la conversione Unicode, quindi se hai in giro alcuni documenti UTF-16 e vuoi leggerli come UTF-8, Pugi fornirà. Ha anche un'implementazione di XPath 1.0, se hai bisogno di quel genere di cose.
Ma Pugi è ancora abbastanza veloce. Come RapidXML, non ha dipendenze ed è distribuito sotto la licenza MIT.
Leggere documenti enormi
Devi leggere documenti misurati in gigabyte . Forse le stai ottenendo dallo stdin, alimentato da qualche altro processo. Oppure li stai leggendo da file di grandi dimensioni. O qualunque cosa. Il punto è che ciò di cui hai bisogno è non farlo dover leggere l'intero file in memoria tutto in una volta per poterlo elaborare.
Tu hai scelto:
libxml2
L'API in stile SAX di Xerces funzionerà con questa capacità, ma LibXML2 è qui perché è un po 'più facile da lavorare. Un'API in stile SAX è un'API push: inizia l'analisi di uno stream e genera eventi che devi catturare. Sei costretto a gestire il contesto, lo stato e così via. Il codice che legge un'API in stile SAX è molto più diffuso di quanto si possa sperare.
L' xmlReader
oggetto di LibXML2 è un'API pull. Si chiede di passare al nodo o all'elemento XML successivo; non ti è stato detto. Ciò ti consente di archiviare il contesto come ritieni opportuno, di gestire entità diverse in un modo molto più leggibile nel codice rispetto a una serie di callback.
alternative
Expat
Expat è un noto parser C ++ che utilizza un'API pull-parser. È stato scritto da James Clark.
Lo stato corrente è attivo. La versione più recente è la 2.2.9, rilasciata il (25-09-2019).
LlamaXML
È un'implementazione di un'API in stile StAX. È un pull-parser, simile a quello di LibXML2xmlReader
parser .
Ma non è stato aggiornato dal 2005. Quindi, ancora, Caveat Emptor.
Supporto XPath
XPath è un sistema per interrogare elementi all'interno di un albero XML. È un modo pratico per nominare in modo efficace un elemento o una raccolta di elementi con proprietà comuni, usando una sintassi standardizzata. Molte librerie XML offrono supporto XPath.
Ci sono effettivamente tre scelte qui:
- LibXML2 : fornisce il supporto completo per XPath 1.0. Ancora una volta, si tratta di un'API C, quindi se questo ti disturba, ci sono alternative.
- PugiXML : viene fornito anche con il supporto XPath 1.0. Come sopra, è più un'API C ++ che LibXML2, quindi potresti sentirti più a tuo agio.
- TinyXML : non viene fornito con il supporto XPath, ma è disponibile la libreria TinyXPath . TinyXML sta subendo una conversione alla versione 2.0, che modifica significativamente l'API, quindi TinyXPath potrebbe non funzionare con la nuova API. Come TinyXML stesso, TinyXPath è distribuito sotto la licenza zLib.
Basta avere il lavoro fatto
Quindi, non ti interessa la correttezza XML. Le prestazioni non sono un problema per te. Lo streaming è irrilevante. Tutto quello che vuoi è qualcosa che metta in memoria l'XML e ti permetta di incollarlo di nuovo sul disco. Quello che ti interessa è l'API.
Vuoi un parser XML che sia piccolo, facile da installare, banale da usare e abbastanza piccolo da essere irrilevante per le dimensioni del tuo eseguibile finale.
Tu hai scelto:
TinyXML
Ho inserito TinyXML in questo slot perché è semplice da usare quanto i parser XML. Sì, è lento, ma è semplice ed evidente. Ha molte funzioni utili per convertire gli attributi e così via.
Scrivere XML non è un problema in TinyXML. Basta solo new
alcuni oggetti, attaccarli insieme, inviare il documento a un std::ostream
e tutti sono felici.
C'è anche qualcosa di un ecosistema costruito attorno a TinyXML, con un'API più intuitiva e persino un'implementazione XPath 1.0 sovrapposta.
TinyXML utilizza la licenza zLib, che è più o meno la licenza MIT con un nome diverso.