Який XML-аналізатор я повинен використовувати в C ++? [зачинено]


344

У мене є документи XML, які мені потрібно проаналізувати та / або мені потрібно створити XML документи та записати їх у текст (або файли, або пам'ять). Оскільки стандартна бібліотека C ++ не має для цього бібліотеки, що я повинен використовувати?

Примітка. Це має бути остаточним питанням для цього питання C ++ - FAQ. Так що так, це дублікат інших. Я не просто відповів на ці інші запитання, тому що вони, як правило, задавали щось дещо більш конкретне. Це питання є більш загальним.


Мені подобається tiCpp code.google.com/p/ticpp , документи не великі (поки що?), Але я люблю бібліотеку, приємний чистий код.

Я написав власну github.com/igagis/mikroxml
igagis

Відповіді:


679

Як і у стандартних бібліотечних контейнерах, яку бібліотеку ви повинні використовувати, залежить від ваших потреб. Ось зручна блок-схема:

введіть тут опис зображення

Тож перше питання таке: що вам потрібно?

Мені потрібна повна відповідність XML

Гаразд, тому вам потрібно обробити XML. Не іграшка XML, справжня XML. Потрібно вміти читати та записувати всю специфікацію XML, а не лише розрядні біти, що легко розбираються. Вам потрібні простори імен, DocTypes, підміна сутності, твори. Специфікація W3C XML в цілому.

Наступне питання: чи повинен ваш API відповідати DOM чи SAX?

Мені потрібна точна DOM та / або відповідність SAX

Гаразд, значить, вам дійсно потрібен API, щоб бути DOM та / або SAX. Це не може бути просто аналізатор натискання в стилі SAX або збережений парсер у стилі DOM. Він повинен бути фактичним DOM або фактичним SAX, наскільки це дозволяє C ++.

Ви вибрали:

Ксерси

Це ваш вибір. Це майже єдиний C ++ XML-аналізатор / записувач, який має повну (або настільки близьку, як це дозволяє C ++) DOM та SAX. Він також має підтримку XInclude, підтримку XML-схеми та безліч інших функцій.

Він не має реальних залежностей. Він використовує ліцензію Apache.

Мене не хвилює відповідність DOM та / або SAX

Ви вибрали:

LibXML2

LibXML2 пропонує інтерфейс у стилі С (якщо це насправді турбує вас, перейдіть на Xerces), хоча інтерфейс є хоча б дещо об'єктним і легко перетворюється. Він надає безліч функцій, як підтримка XInclude (із зворотними дзвінками, щоб ви могли повідомити, звідки він отримує файл), розпізнавальник XPath 1.0, підтримка RelaxNG та Schematron (хоча повідомлення про помилки залишають бажати кращого) та т.д.

Він має залежність від iconv, але його можна налаштувати і без цієї залежності. Хоча це означає, що у вас буде більш обмежений набір можливих текстових кодувань, які він може розібрати.

Він використовує ліцензію MIT.

Мені не потрібна повна відповідність XML

Гаразд, тому повне відповідність XML для вас не має значення. Ваші документи XML повністю або під вашим контролем, або гарантовано використовувати "основний підмножина" XML: немає просторів імен, об'єктів тощо.

То що вам важливо? Наступне питання: що для вас найважливіше в роботі XML?

Максимальна продуктивність розбору XML

Вашій програмі потрібно взяти XML і перетворити її в структуру даних C ++ так швидко, як це можливо, перетворення.

Ви вибрали:

RapidXML

Цей XML-аналізатор - це саме те, що написано на бляшанці: швидкий XML. Це навіть не стосується витягування файлу в пам'ять; як це відбувається, залежить від вас. Те, з чим він працює, - це аналіз їх на низку структур C ++, до яких можна отримати доступ. І це робиться приблизно так швидко, як потрібно для сканування файлу в байті.

Звичайно, немає такого поняття, як безкоштовний обід. Як і більшість парсерів XML, яким не важливо специфікацію XML, Rapid XML не торкається просторів імен, DocTypes, сутностей (за винятком сутності символів та 6 основних XML) тощо. Отже, в основному, вузли, елементи, атрибути тощо.

Крім того, це аналізатор стилю DOM. Тому потрібно прочитати весь текст. Однак те, що він не робить, - це скопіювати будь-який із цього тексту (як правило). Швидкість, з якою RapidXML отримує більшу частину своєї швидкості, - це перехід до рядків на місці . Це вимагає більшого управління пам’яттю з вашого боку (ви повинні підтримувати цей рядок живим, поки RapidXML дивиться на нього).

DOM RapidXML - це голі кістки. Ви можете отримати рядкові значення для речей. Ви можете шукати атрибути за іменем. Ось про це. Немає функцій зручності, щоб перетворити атрибути в інші значення (числа, дати тощо). Ви просто отримуєте струни.

Ще одним недоліком у RapidXML є те, що він болісно пише XML. Це вимагає, щоб ви зробили багато явного розподілу пам'яті імен рядків, щоб створити свою DOM. Він надає певний буфер рядків, але це все ще потребує великої явної роботи у вашому кінці. Це, звичайно, функціонально, але це біль.

Він використовує ліцензію MIT. Це бібліотека, лише для заголовків, без залежностей.

  • Існує "патч GitHub" RapidXML, який дозволяє йому також працювати з просторами імен.

Я дбаю про продуктивність, але не дуже багато

Так, для вас важлива продуктивність. Але, можливо, вам потрібно щось трохи менше босих кісток. Можливо, щось, що може працювати з більшою кількістю Unicode, або не вимагає стільки управління пам'яттю, керованої користувачем Продуктивність все ще важлива, але ви хочете чогось менш прямого.

Ви вибрали:

PugiXML

Історично це служило натхненням для RapidXML. Але два проекти розійшлися, і Pugi пропонує більше можливостей, тоді як RapidXML повністю орієнтований на швидкість.

PugiXML пропонує підтримку конверсії Unicode, тому якщо у вас є кілька документів UTF-16 і хочете прочитати їх як UTF-8, Pugi надасть. Він навіть має реалізацію XPath 1.0, якщо вам потрібна така річ.

Але Пугі все ще досить швидкий. Як і у RapidXML, він не має залежностей і поширюється під ліцензією MIT.

Читання величезних документів

Вам потрібно прочитати документи, які вимірюються в гігабайтах за розміром. Можливо, ви отримуєте їх від stdin, годуючись якимись іншими процесами. Або ви читаєте їх з масивних файлів. Або що завгодно. Справа в тому, що вам потрібно - не робити потрібно читати весь файл у пам'яті відразу, щоб обробити його.

Ви вибрали:

LibXML2

API SAX-стилю Xerces працює в цій якості, але тут є LibXML2, оскільки з цим трохи простіше працювати. API стилю SAX - це push-API: він починає розбирати потік і просто запускає події, які вам доведеться спіймати. Ви змушені керувати контекстом, станом тощо. Код, який читає API в стилі SAX, набагато більше, ніж можна сподіватися.

Об'єктом LibXML2 xmlReaderє API API. Ви просите перейти до наступного вузла або елемента XML; вам не кажуть. Це дозволяє зберігати контекст так, як вам здається, обробляти різні об'єкти таким чином, що в коді можна читати набагато більше, ніж купу зворотних викликів.

Альтернативи

Експат

Expat - це відомий аналізатор C ++, який використовує API "pull-parser". Це написав Джеймс Кларк.

Поточний статус активний. Найновіша версія - 2.2.9, яка вийшла в світ (2019-09-25).

LlamaXML

Це реалізація API стилю StAX. Це pull-аналізатор, схожий на xmlReaderаналізатор LibXML2 .

Але він не оновлювався з 2005 року. Отже, знову, Caveat Emptor.

Підтримка XPath

XPath - це система запиту елементів у дереві XML. Це зручний спосіб ефективного іменування елемента або колекції елемента за загальними властивостями, використовуючи стандартизований синтаксис. Багато бібліотек XML пропонують підтримку XPath.

Тут є три варіанти:

  • LibXML2 : Він забезпечує повну підтримку XPath 1.0. Знову ж таки, це API API, тож якщо це вас турбує, є альтернативи.
  • PugiXML : Також він постачається з підтримкою XPath 1.0. Як вище, це більше API C ++, ніж LibXML2, тому вам може бути зручніше з ним.
  • TinyXML : Він не постачається з підтримкою XPath, але є бібліотека TinyXPath, яка забезпечує його. TinyXML проходить перехід до версії 2.0, що суттєво змінює API, тому TinyXPath може не працювати з новим API. Як і сам TinyXML, TinyXPath поширюється під ліцензією zLib.

Просто займіть роботу

Отже, вам не байдуже правильність XML. Продуктивність не є проблемою для вас. Трансляція не має значення. Все, що вам потрібно, - це те, що отримує XML в пам’яті і дозволяє вам знову вставити його на диск. Що вас цікавить - це API.

Ви хочете, щоб аналізатор XML був невеликий, простий в установці, тривіальний у використанні та досить малий, щоб не мати значення для вашого можливого розміру виконуваного файлу.

Ви вибрали:

TinyXML

Я помістив TinyXML в цей слот, тому що він приблизно такий, як braindead простий у використанні, як отримують XML-аналізатори. Так, це повільно, але це просто і очевидно. Він має багато зручних функцій для перетворення атрибутів тощо.

Написання XML не є проблемою в TinyXML. Ви просто newпідготуйте деякі об'єкти, з'єднайте їх, відправте документ на std::ostreamі всі задоволені.

Є також екосистема, побудована навколо TinyXML, з більш зручним для ітераторів API і навіть реалізацією XPath 1.0, що розміщена поверх нього.

TinyXML використовує ліцензію zLib, яка є більшою чи меншою мірою Ліцензією MIT з іншим іменем.


6
Це трохи схоже на копію-вставку. Чи можете ви зв’язати вихідний документ?
Джоель

28
@Joel: досить часто, коли хтось відповідає на їхнє власне запитання з гарним довгим повідомленням, це тому, що вони слідують у дусі поради Джеффа - особливо тому, що те, що схоже на таке питання, часто можна закрити, перш ніж хороша відповідь може бути опублікованим, якщо людина записує відповідь прямо тут і там. Виділивши трохи часу, щоб підготувати відповідь, перш ніж він поставив питання :) Нікол надає нам усім відмінного кандидата на запитання Close-> Дублікати в майбутньому.
sarnold

28
@Joel: Боюся, що не можу. Це був лише тимчасовий документ, який я скопіював у «Блокноті ++». Я ніколи його не врятував, тому не можу пов’язати вас із цим;)
Nicol Bolas

6
Можливо, варто згадати новішу версію TinyXML: TinyXML-2 використовує аналогічний API для TinyXML-1 і такі ж багаті тестові випадки. Але реалізація парсера повністю переписана, щоб зробити його більш доцільним для використання в грі. Він використовує менше пам’яті, швидший і використовує набагато небагато пам'яті.
johnbakers

6
Мені подобається це питання та відповіді, але я вважаю це занадто упередженим Unix. Ніякої згадки про MSXML та XmlLite? Якщо переносимість мультиплікації є вашою причиною виключення цих питань, то це слід чітко вказати у запитанні та відповіді. (Інакше деякі люди можуть обрати, наприклад, Libxml2 для проекту, призначеного лише для Windows, який вимагає головних болів, яких можна було б легко уникнути.)
Scrontch

17

Існує ще один підхід до обробки XML, який, можливо, ви хочете розглянути, називається прив'язка даних XML. Особливо, якщо ви вже маєте офіційну специфікацію свого словника XML, наприклад, у XML-схемі.

Прив'язка даних XML дозволяє використовувати XML, фактично не роблячи жодного аналізу XML або серіалізації. Компілятор зв’язування даних автоматично генерує весь код низького рівня та представляє розроблені дані у вигляді класів C ++, які відповідають вашому домену програми. Потім ви працюєте з цими даними, викликаючи функції та працюючи з типами C ++ (int, double та ін.) Замість того, щоб порівнювати рядки та розбирати текст (це те, що ви робите з API низького рівня доступу XML, наприклад, DOM або SAX).

Дивіться, наприклад, реалізацію ядерних зв'язків XML з відкритим кодом, яку я написав, CodeSynthesis XSD і, для більш легкої ваги, незалежної версії, CodeSynthesis XSD / e .


13
Я не проти публікації, але політика ТА говорить, що якщо ви пропонуєте щось, що ви написали, вам слід згадати, що ви його написали, в інтересах повного розголошення.
Нікол Болас

@Nicol Я відредагував це у відповідь.
JBentley

Можливо, цей список корисний, але я не міг з’ясувати, хто такі автори цього списку (без публічного оприлюднення я не можу зрозуміти, чи є описи та оцінки значущими). Можливо, можна подивитися на робочу групу зв’язування даних W3C, яка перелічує кілька інструментів прив'язки даних, які знаходяться у відкритому доступі та використовувались для тестування та звітності (повне розкриття: я не пов'язаний із CodeSynthesis. Я допоміг gsoap, переліченому у W3C інструменти).
доктор Алекс RE

1

Ще одна примітка про Expat: варто подивитися на роботу вбудованих систем. Однак документація, яку ви, швидше за все, знайдете в Інтернеті, є давньою та неправильною. У вихідному коді насправді є досить ґрунтовні коментарі на рівні функцій, але для цього знадобиться певне перегляду.


0

Покладіть і мою.

http://www.codeproject.com/Articles/998388/XMLplusplus-version-The-Cplusplus-update-of-my-XML

Немає функцій перевірки XML, але швидко.


2
Це швидше чи ширше, ніж RapidXML? Або PugiXML? Доменний простір для "швидкого, не зовсім XML" аналізатора C ++ був досить добре висвітлений.
Нікол Болас

0

Добре тоді. Я створив новий, оскільки жоден із списку не підтвердив мої потреби.

Переваги:

  1. Поточний інтерфейс API Streaming на низькому рівні ( схоже на Java StAX )
  2. Винятки та підтримувані режими RTTI
  3. Обмеження на використання пам’яті, підтримку великих файлів (тестується на 100 Мбіт XMark від, швидкість залежить від обладнання)
  4. Підтримка UNICODE та автоматичне виявлення для кодування вхідних джерел
  5. API високого рівня для читання в структури / POCO
  6. API програмування мета-програмування для запису та генерації XSD із структур / POCO з підтримкою xml-структури (атрибутів та вкладених тегів) (для покоління XSD потрібен RTTI, але його можна використовувати лише при налагодженні, щоб зробити це один раз)
  7. C ++ 11 - GCC та VC ++ 15+

Недоліки:

  1. Перевірка DTD та XSD ще не надана
  2. Отримання XML / XSD протоколом HTTP / HTTPS ще не виконано
  3. Нова бібліотека

Проект будинку


1
Чи можете ви додати орієнтири?
Вадим Перетокін

-1

У компанії Security Globe , Inc. ми використовуємо quickxml . Ми спробували всі інші, але, швидше за все, швидкий вибір для нас є.

Ось приклад:

 rapidxml::xml_document<char> doc;
    doc.parse<0>(xmlData);
    rapidxml::xml_node<char>* root = doc.first_node();

    rapidxml::xml_node<char>* node_account = 0;
    if (GetNodeByElementName(root, "Account", &node_account) == true)
    {
        rapidxml::xml_node<char>* node_default = 0;
        if (GetNodeByElementName(node_account, "default", &node_default) == true)
        {
            swprintf(result, 100, L"%hs", node_default->value());
            free(xmlData);
            return true;
        }
    }
    free(xmlData);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.