Mam dokumenty XML, które muszę przeanalizować i / lub muszę zbudować dokumenty XML i zapisać je w tekście (pliki lub pamięć). Ponieważ standardowa biblioteka C ++ nie ma biblioteki do tego, czego powinienem użyć?
Uwaga: To ma być ostateczne pytanie w stylu C ++ - FAQ. Tak, to duplikat innych. Nie odpowiedziałem po prostu na te inne pytania, ponieważ zwykle prosiły o coś nieco bardziej szczegółowego. To pytanie jest bardziej ogólne.
c++
xml-parsing
c++-faq
Nicol Bolas
źródło
źródło
Odpowiedzi:
Podobnie jak w przypadku standardowych kontenerów bibliotecznych, biblioteka, której należy użyć, zależy od potrzeb. Oto wygodny schemat blokowy:
Pierwsze pytanie brzmi: czego potrzebujesz?
Potrzebuję pełnej zgodności z XML
OK, więc musisz przetworzyć XML. Nie zabawki XML, prawdziwy XML. Musisz być w stanie odczytać i zapisać całą specyfikację XML, a nie tylko nisko położone, łatwe do przeanalizowania bity. Potrzebujesz przestrzeni nazw, typów dokumentów, podstawiania encji, prac. Specyfikacja W3C XML w całości.
Następne pytanie brzmi: czy Twój interfejs API musi być zgodny z DOM lub SAX?
Potrzebuję dokładnej zgodności z DOM i / lub SAX
OK, więc naprawdę potrzebujesz interfejsu API, aby był DOM i / lub SAX. Nie może to być po prostu parser wypychający w stylu SAX lub zachowany parser w stylu DOM. To musi być rzeczywisty DOM lub rzeczywisty SAX, do tego stopnia, że C ++ pozwala.
Wybrałeś:
Xerces
To Twój wybór. Jest to właściwie jedyny parser / moduł zapisujący XML C ++, który ma pełną (lub tak bliską, jak pozwala C ++) zgodność DOM i SAX. Ma także obsługę XInclude, obsługę schematu XML i mnóstwo innych funkcji.
Nie ma żadnych rzeczywistych zależności. Korzysta z licencji Apache.
Nie dbam o zgodność z DOM i / lub SAX
Wybrałeś:
LibXML2
LibXML2 oferuje interfejs w stylu C (jeśli naprawdę Ci to przeszkadza, skorzystaj z Xerces), chociaż interfejs jest co najmniej w pewnym stopniu oparty na obiektach i łatwo go zapakować. Zapewnia wiele funkcji, takich jak obsługa XInclude (z oddzwanianiem, dzięki czemu można powiedzieć, skąd pobiera plik), rozpoznawanie XPath 1.0, obsługa RelaxNG i Schematron (choć komunikaty o błędach pozostawiają wiele do życzenia) i itd.
Ma zależność od iconv, ale można ją skonfigurować bez tej zależności. Chociaż oznacza to, że będziesz mieć bardziej ograniczony zestaw możliwych kodowań tekstowych, które może analizować.
Korzysta z licencji MIT.
Nie potrzebuję pełnej zgodności z XML
OK, więc pełna zgodność XML nie ma dla ciebie znaczenia. Twoje dokumenty XML są w pełni pod twoją kontrolą lub masz gwarancję, że użyjesz „podstawowego podzbioru” XML: bez przestrzeni nazw, encji itp.
Co jest dla ciebie ważne? Następne pytanie brzmi: co jest dla Ciebie najważniejsze w pracy nad XML?
Maksymalna wydajność analizowania XML
Twoja aplikacja musi pobrać XML i przekształcić go w struktury danych C ++ tak szybko, jak to możliwe.
Wybrałeś:
RapidXML
Ten parser XML jest dokładnie tym, co jest napisane na puszce: rapid XML. Nawet nie zajmuje się wciąganiem pliku do pamięci; jak to się stanie, zależy od ciebie. Zajmuje się analizowaniem tego w szeregu struktur danych C ++, do których można uzyskać dostęp. I robi to tak szybko, jak potrzeba do skanowania pliku bajt po bajcie.
Oczywiście nie ma czegoś takiego jak darmowy lunch. Jak większość parserów XML, które nie dbają o specyfikację XML, Rapid XML nie dotyka przestrzeni nazw, typów dokumentów, encji (z wyjątkiem encji znakowych i 6 podstawowych XML) i tak dalej. Więc w zasadzie węzły, elementy, atrybuty i tym podobne.
Ponadto jest to parser w stylu DOM. Wymaga to więc przeczytania całego tekstu. Jednak to, czego nie robi, to skopiowanie dowolnego tekstu (zwykle). Sposób, w jaki RapidXML osiąga największą prędkość, polega na odwoływaniu się do ciągów w miejscu . Wymaga to większego zarządzania pamięcią z twojej strony (musisz utrzymywać ten ciąg przy życiu, gdy RapidXML na niego patrzy).
DOM RapidXML jest zupełnie pusty. Możesz uzyskać wartości ciągu dla rzeczy. Możesz wyszukiwać atrybuty według nazwy. O to chodzi. Nie ma żadnych funkcji ułatwiających przekształcenie atrybutów w inne wartości (liczby, daty itp.). Po prostu dostajesz sznurki.
Innym minusem RapidXML jest to, że pisanie XML jest bolesne . Wymaga dużo jawnej alokacji pamięci nazw ciągów w celu zbudowania DOM. Zapewnia rodzaj bufora ciągów, ale wciąż wymaga dużo wyraźnej pracy po twojej stronie. Jest to z pewnością funkcjonalne, ale korzystanie z niego jest uciążliwe.
Korzysta z licencji MIT. Jest to biblioteka tylko nagłówka bez zależności.
Dbam o wydajność, ale nie aż tak bardzo
Tak, wydajność ma dla Ciebie znaczenie. Ale może potrzebujesz czegoś mniej nagiego. Może coś, co może obsłużyć więcej Unicode lub nie wymaga tak dużo zarządzania pamięcią kontrolowanego przez użytkownika. Wydajność jest nadal ważna, ale chcesz czegoś mniej bezpośredniego.
Wybrałeś:
PugiXML
Historycznie było to inspiracją dla RapidXML. Ale oba projekty się rozeszły, Pugi oferuje więcej funkcji, podczas gdy RapidXML koncentruje się całkowicie na szybkości.
PugiXML oferuje obsługę konwersji Unicode, więc jeśli masz jakieś dokumenty UTF-16 i chcesz je przeczytać jako UTF-8, Pugi zapewni. Ma nawet implementację XPath 1.0, jeśli potrzebujesz czegoś takiego.
Ale Pugi jest wciąż dość szybki. Podobnie jak RapidXML, nie ma żadnych zależności i jest rozpowszechniany na licencji MIT.
Czytanie ogromnych dokumentów
Musisz przeczytać dokumenty mierzone w gigabajtach . Może otrzymujesz je ze standardowego źródła, będąc zasilanym przez inny proces. Lub czytasz je z ogromnych plików. Lub cokolwiek. Chodzi o to, że nie musisz od razu czytać całego pliku do pamięci, aby go przetworzyć.
Wybrałeś:
LibXML2
Interfejs API Xerces w stylu SAX będzie działał w tej roli, ale LibXML2 jest tutaj, ponieważ jest nieco łatwiej z nim pracować. Interfejs API w stylu SAX jest interfejsem API typu push: rozpoczyna analizowanie strumienia i po prostu odpala zdarzenia, które należy przechwycić. Jesteś zmuszony zarządzać kontekstem, stanem i tak dalej. Kod odczytujący interfejs API w stylu SAX jest znacznie bardziej rozpowszechniony, niż można by się spodziewać.
xmlReader
Obiekt LibXML2 to pull-API. Państwo poprosić , aby przejść do następnego węzła XML lub elementu; nie powiedziano ci. Umożliwia to przechowywanie kontekstu według własnego uznania i obsługę różnych elementów w sposób znacznie bardziej czytelny w kodzie niż kilka wywołań zwrotnych.Alternatywy
Expat
Expat jest dobrze znanym parserem C ++, który wykorzystuje API parsera pull-parser. Zostało napisane przez Jamesa Clarka.
Jego obecny status jest aktywny. Najnowsza wersja to 2.2.9, która została wydana (2019-09-25).
LlamaXML
Jest to implementacja interfejsu API w stylu StAX. Jest to parser typu pull-parser, podobny do
xmlReader
parsera LibXML2 .Ale nie był aktualizowany od 2005 roku. Więc ponownie, Caveat Emptor.
Obsługa XPath
XPath to system do zapytań o elementy w drzewie XML. Jest to przydatny sposób skutecznego nazywania elementu lub kolekcji elementu według wspólnych właściwości przy użyciu standardowej składni. Wiele bibliotek XML oferuje obsługę XPath.
Istnieją tutaj skutecznie trzy opcje:
Po prostu zrób pracę
Tak więc nie obchodzi Cię poprawność XML. Wydajność nie stanowi dla ciebie problemu. Streaming nie ma znaczenia. Wszystko, czego potrzebujesz, to coś , co przenosi XML do pamięci i pozwala ponownie przykleić go z powrotem na dysk. To , na czym Ci zależy, to API.
Potrzebujesz parsera XML, który będzie mały, łatwy w instalacji, trywialny w użyciu i wystarczająco mały, aby nie miał znaczenia dla ostatecznego rozmiaru pliku wykonywalnego.
Wybrałeś:
TinyXML
Umieściłem TinyXML w tym gnieździe, ponieważ jest on tak prosty w obsłudze jak Braindead, jak parsery XML. Tak, jest wolny, ale prosty i oczywisty. Ma wiele funkcji ułatwiających konwersję atrybutów i tak dalej.
Pisanie XML nie jest problemem w TinyXML. Po prostu
new
zbierasz niektóre obiekty, łączysz je ze sobą, wysyłasz dokument dostd::ostream
i wszyscy są zadowoleni.Jest też coś w rodzaju ekosystemu zbudowanego wokół TinyXML, z API bardziej przyjaznym dla iteratorów, a nawet warstwą implementacji XPath 1.0.
TinyXML korzysta z licencji zLib, która jest mniej więcej licencją MIT o innej nazwie.
źródło
Istnieje inne podejście do obsługi XML, które warto rozważyć, nazywane wiązaniem danych XML. Zwłaszcza jeśli masz już formalną specyfikację swojego słownictwa XML, na przykład w schemacie XML.
Powiązanie danych XML umożliwia korzystanie z XML bez faktycznego analizowania lub serializacji XML. Kompilator powiązania danych automatycznie generuje cały kod niskiego poziomu i prezentuje przeanalizowane dane jako klasy C ++, które odpowiadają Twojej domenie aplikacji. Następnie pracujesz z tymi danymi, wywołując funkcje i pracując z typami C ++ (int, double, itp.) Zamiast porównywania ciągów i parsowania tekstu (co robisz z interfejsami API niskiego poziomu, takimi jak DOM lub SAX).
Zobacz na przykład napisaną przeze mnie implementację wiązania danych XML o otwartym kodzie źródłowym, CodeSynthesis XSD oraz, w przypadku lżejszej, niezależnej wersji, CodeSynthesis XSD / e .
źródło
Jeszcze jedna uwaga na temat programu Expat: warto przyjrzeć się pracy systemów wbudowanych. Jednak dokumentacja, którą najprawdopodobniej znajdziesz w Internecie, jest starożytna i błędna. Kod źródłowy faktycznie ma dość dokładne komentarze na poziomie funkcji, ale ich zrozumienie zajmie trochę czasu.
źródło
Połóż też mój.
http://www.codeproject.com/Articles/998388/XMLplusplus-version-The-Cplusplus-update-of-my-XML
Brak funkcji sprawdzania poprawności XML, ale szybko.
źródło
Okej więc. Stworzyłem nową, ponieważ żadna z list nie zaspokoiła moich potrzeb.
Korzyści:
Niedogodności:
Projekt domu
źródło
W Secured Globe , Inc. używamy rapidxml . Próbowaliśmy wszystkich innych, ale rapidxml wydaje się być dla nas najlepszym wyborem.
Oto przykład:
źródło