C++用のベストなXMLパーサライブラリ



XMLパーサは、実用レベルから習作レベルまで、雨後の筍ほどもある。C++で使えるライブラリを探した。

機能性

XML関係の仕様は, XSLT, XQuery, XLink, XPointer, XPath など多くある。

XLink 1.1 (XLink 1.0 の不具合修正), XPointer は XBRL で使われている。DocBook v5 は XLink, XInclude 1.0 を使っている。SVG 1.1 は XLink を使っている。OpenDocument v1.3 は, MathML 2.0, RELAX NG, SVG 1.1, XForms 1.0, XLink, XPath 1.0, XSL, XSLT など.

XMLパーサは, これらの仕様のうちアプリケイションの基礎となるものについて、最低限 XPath ぐらいは備えていてほしい。

XSLT, XPath, XQuery

XSLT, XPath, XQuery は組み合わせがある。

ヴァージョン対応表
XSLT XPath XQuery
XSLT 3.0 (2017-06-08) XPath 3.1 (2017-03-21) XQuery 3.1 (2017-03-21)
XSLT 2.0 or XSLT 3.0 XPath 3.0 (2014-04-08) XQuery 3.0 (2014-04-08)
XSLT 2.0 (2007-01-23). 2nd 2021-03-30. XPath 2.0 (2007-01-23). 2nd 2010-12-14. XQuery 1.0 (2007-01-23). 2nd 2010-12-14.

XQuery 3.0 は XPath 3.0 の拡張。XQuery 1.0 は XPath 2.0 の拡張。

XPath 2.0 以降は強い型付けで, XPath 1.0 と非互換。処理系が XPath 1.0 compatibility mode (旧名 type exception policy) 値として真を返す場合, XPath 1.0 との互換性を提供。XSLT 2.0 でも, xsl:supports-backwards-compatibility システムプロパティが "yes" を返すとき, 後方互換性をサポートする。

フレームワークの一部

XMLパーサ「だけ」を使うことは少ない。利用するフレームワークがXML関連のライブラリを提供していれば、まずい実装でない限り、それを使えばいい。

Qt5. Qt6で廃止

Qt5: Qt XMLモジュールがある。SAX を使いたい場合, core モジュールの QXmlStreamReader クラスと QXmlStreamWriter クラスを使え。DOM は xml モジュールの QDomDocument クラス.

Qt5 の xmlpatterns モジュールは, XPath 2.0, XQuery 1.0, XSLT および XML Schema を提供。しかし、Qt6 で単に廃止された。XMLは不人気.

Qt5 QDomDocument クラスは DTD を解釈する。挙動を変更するフラグなどはなさそう。External entity (外部実体) 宣言および実体参照はサポートしない (XEE attack は効かない). Billion laughs attack もパースを打ち切るので効かない。

POCO C++ Libraries

Poco::XML 名前空間. Node インタフェイスの getNodeByPath() メソッド, getNodeByPathNS() メソッドで simplified XPath expression をサポート。フルのXPath ではない.

POCO は openFrameworks の一部になっている。独立した多数のライブラリを組み合わせるより、調整されたフレームワークを使うのは、悪くない選択。

Fedora 36 Debian 11 openSUSE 15.4
poco-devel 1.11.2 libpoco-dev 1.10.0 poco-devel 1.10.1

単品の有力な実装

ということで, 有力なものを以下に示す。後ろに選外も並べておく。

Saxon-HE/C

提供 ライセンス
Saxonica社 MPL 2.0 (Home Edition)

HE (Home Edition), EE (Enterprise Edition) などがある。基本は Java, .NET 用で, それをC/C++向けにビルドしたもの。Saxon/C v1.2.1 は Saxon v9.9相当. SaxonC 11 はヴァージョン番号が Java版と同期. Saxon 10 product comparison (Feature Matrix)

唯一の XSLT 3.0, XQuery 3.1 and XPath 3.1 フルサポート. XInclude.

DTD (カタログのカスタマイズ可) and XML Schema 1.0/1.1 validation. XML Schema サポートは Saxon-EE のみ.

公式サイトで Linux, MacOS, Windows バイナリを提供。

CentOS 8 Fedora 34 Debian openSUSE 15.4
パッケージなし パッケージなし libsaxonhe-java のみ (C版がない) saxon8 (Java), saxon9 (Java)

信頼できないソースのXMLデータを扱うときは, 次を false にする。

  • http://saxon.sf.net/feature/parserFeature?uri=http%3A//xml.org/sax/features/external-general-entities 外部一般実体
  • http://saxon.sf.net/feature/parserFeature?uri=http%3A//xml.org/sax/features/external-parameter-entities 外部パラメータ実体

Xerces-C++ 旧 IBM XML for C++ (XML4C)

提供 ライセンス
Apache Apache Software License 2.0

DOM Level 3 and SAX 1.0/2.0, XInclude. DTD および XML Schema. 各ディストリビューションでパッケージ化されている。

CentOS 8 Debian 11 openSUSE 15.4
xerces-c v3.2.2 libxerces-c-dev v3.2.3 libxerces-c-devel 3.2.3

Xerces-C は XPath を備えない。次と組み合わせる。XQuery & XPath 2.0 は XQilla のみ。しかし Debian 以外のディストリビューションでパッケージ化されていない. Xalan のほうがパッケージがあり, わずかにメンテナンスが続いている。

  • Xalan-C++ XSLT processor XSLT 1.0 and XPath 1.0.
    CentOS 8 Debian 11 openSUSE 15.4
    xalan-c v1.12.0 libxalan-c-dev v1.12 (2020) libxalan-c-devel 1.11 (2014)
  • XQilla XQuery and XPath 2 library XQuery 1.0 (一部 XQuery 3.0), XSLT 2.0 and XPath 2.0.
    Fedora 34 CentOS 7 CentOS 8 Debian 11 openSUSE 15.4
    パッケージあり パッケージあり なし libxqilla-dev v2.3.4 なし.

信頼できないソースのXMLデータを使うときは, DTDを完全に無効化する (fgDOMDisallowDoctype) か, 次のようにする.

XercesDOMParserAbstractDOMParser から派生している。

XercesDOMParser *parser = new XercesDOMParser;
parser->setCreateEntityReferenceNodes(true);  // false のときに展開する. 紛らわしい.
parser->setDisableDefaultEntityResolution(true);

SAXParser (SAX 1.0; 古い) も設定変更する.

SAXParser* parser = new SAXParser;
parser->setDisableDefaultEntityResolution(true);

SAX2XMLReader (SAX2) はやり方が違う。デフォルト値は false になっている。

SAX2XMLReader* reader = XMLReaderFactory::createXMLReader();
parser->setFeature(XMLUni::fgXercesDisableDefaultEntityResolution, true);

pugixml

提供 ライセンス
Arseny Kapoulkine氏 MIT License

DTD or XML Schema 検証は含まない (non-validating のみ)。実体参照 entity reference のカスタマイズも不能。割り切った用途にはよい。

DOM-like interface. スピードが売り。Better than RapidXML. XPath 1.0. Full Unicode support.

CentOS 8 Debian 11 openSUSE 15.4
v1.11.4 v1.11.4 pugixml-devel 1.11.4

libxml2 (plain C)

提供 ライセンス
Daniel Veillard氏 MIT License

Plain Cだが、幅広く使われているので、挙げておく。

XPath 1.0. DTDのみサポートで XML Schema は未対応。

libxslt が libxml2 を使っている。Ruby Nokogiri requires libxml2 and libxslt.

CentOS 8 Debian 11
libxml2 v2.9.7, libxslt v1.1.32 libxslt1-dev v1.1.34

信頼できないソースのXML データを使うときは, options として次を指定しないようにする. DTDの無効化はできないかな?

  • XML_PARSE_DTDLOAD Load the external subset
  • XML_PARSE_NOENT Substitute entities

未確認

The Incredible C++ XML Parser and JSON Parser http://www.applied-mathematics.net/tools/IXMLParser.html XPath サポートあり。

Zorba - The NoSQL Query Processor http://www.zorba.io/home

XQuery C and C++ API, http://xqc.sourceforge.net/ APIを定めるプロジェクト。この XQC APIに基づくソフトウェアとして Zorba, XQilla がある。

選外

△ AsmXml
最終が2012年。終了。
△ VTD-XML: The Future of XML Processing https://vtd-xml.sourceforge.io/
ライセンス = GPL or コマーシャル.
△ RapidXml
機能性が不足。pugixml を使え。
△ TinyXML-2 http://www.grinninglizard.com/tinyxml2/
surpasses TinyXML-1 http://www.grinninglizard.com/tinyxml/. ✗ XPath
△ libxml++ http://libxmlplusplus.sourceforge.net/
[2021.6 checked] C++ wrapper for libxml2. glibmm はダメだ。
△ libstudxml: modern C++ XML API https://www.codesynthesis.com/projects/libstudxml/
"We replaced a rapidxml parser and not only is libstudxml much faster, but the code is so much clearer."

MIT License. XPath サポートなし。[2022-07] 最新版が2015年のv1.0.1. 終了.

expat (plain C)

もともとは James Clark 作 (v1.2まで). A stream-oriented XML parser library written in C. XPath サポートはなさそう。

CentOS 8 expat-2.2.5. v2.2.0 までは 外部 DTD サブセットの処理に脆弱性がある。[CVE-2017-9233 サンプル付き]

広く使われていて、現在でもメンテナンスされている。しかしながら, ライブラリを作るための基盤として使うもので、直接使うようなものではなさそう。

リンク

XML Vulnerabilities and Attacks cheatsheet XML脆弱性の一覧とサンプル.

XML Based Attacks - OWASP Server Side Request Forgery (SSRF) attack はリソースにアクセスしただけで発生。これはヤバい。

XML External Entity Prevention - OWASP Cheat Sheet Series 各実装での設定。

●●後で確認: REXML の脆弱性: #1104077 Round-trip instability in REXML, 1947526 - CVE-2021-28965 ruby: XML round-trip vulnerability in REXML