C++ ではどの XML パーサーを使用すればよいですか? [closed] 質問する

C++ ではどの XML パーサーを使用すればよいですか? [closed] 質問する

解析する必要がある XML ドキュメントがあり、また XML ドキュメントを構築してテキスト (ファイルまたはメモリ) に書き込む必要があります。C++ 標準ライブラリにはこのためのライブラリがないため、何を使用すればよいでしょうか。

注:これは、これに対する決定的な C++ FAQ スタイルの質問となることを意図しています。したがって、確かに他の質問と重複しています。他の質問は、もう少し具体的なことを尋ねる傾向があったため、単にそれらを流用したわけではありません。この質問は、より一般的なものです。

ベストアンサー1

標準ライブラリ コンテナーと同様に、どのライブラリを使用するかはニーズによって異なります。便利なフローチャートを以下に示します。

ここに画像の説明を入力してください

最初の質問はこれです:何が必要ですか?

完全なXML準拠が必要

わかりました。XML を処理する必要があります。おもちゃの XML ではなく、本物のXML です。低レベルで解析しやすい部分だけでなく、XML 仕様のすべてを読み書きできる必要があります。名前空間、DocType、エンティティ置換などが必要です。W3C XML 仕様全体です。

次の質問は、API は DOM または SAX に準拠する必要があるかどうかです。

正確なDOMおよび/またはSAX準拠が必要です

そうですね、API は DOM または SAX である必要があります。SAX スタイルのプッシュ パーサーや DOM スタイルの保持パーサーだけでは不十分です。C ++ が許す限り、実際の DOM または実際の SAX である必要があります。

あなたが選択しました:

ゼクセス

それはあなたの選択です。これは、DOM と SAX に完全に準拠した (または C++ が許す限りそれに近い) 唯一の C++ XML パーサー/ライターです。また、XInclude サポート、XML スキーマ サポート、およびその他の多数の機能も備えています。

実際の依存関係はありません。Apache ライセンスを使用します。

DOM や SAX の適合性は気にしない

あなたが選択しました:

LibXML2

LibXML2 は C スタイルのインターフェイスを提供します (それが気になる場合は、Xerces を使用してください)。ただし、インターフェイスは少なくともある程度オブジェクト ベースであり、簡単にラップできます。XInclude サポート (ファイルの取得元を知らせるためのコールバック付き)、XPath 1.0 認識機能、RelaxNG および Schematron サポート (ただし、エラー メッセージは改善の余地が大いにあります)など、多くの機能を提供します。

これは iconv に依存しますが、その依存なしに構成することもできます。ただし、これは解析できるテキスト エンコーディングのセットがより制限されることを意味します。

MITライセンスを使用します。

完全なXML準拠は必要ない

そうですね、完全な XML 準拠は問題ではありません。XML ドキュメントは完全に管理されているか、または XML の「基本サブセット」 (名前空間、エンティティなどなし) を使用することが保証されています。

では、あなたにとって何が重要なのでしょうか? 次の質問は、XML 作業であなたにとって最も重要なことは何ですか?

最大のXML解析パフォーマンス

アプリケーションでは、XML をできるだけ高速に C++ データ構造に変換する必要があります。

あなたが選択しました:

ラピッドXML

この XML パーサーは、まさにその名の通り、高速 XML です。ファイルをメモリに取り込むことすらしません。その方法はあなた次第です。処理するのは、それをアクセス可能な一連の C++ データ構造に解析することです。そして、これはファイルをバイトごとにスキャンするのと同じくらいの速さで行われます。

もちろん、ただで手に入るものなどありません。XML 仕様を気にしないほとんどの XML パーサーと同様に、Rapid XML は名前空間、DocType、エンティティ (文字エンティティと 6 つの基本的な XML エンティティを除く) などには触れません。つまり、基本的にはノード、要素、属性などです。

また、これは DOM スタイルのパーサーです。したがって、すべてのテキストを読み込む必要があります。ただし、通常はテキストのコピーは行われません。RapidXML が速度を最大限に引き出す方法は、文字列をその場で参照することです。このため、ユーザー側でより多くのメモリ管理が必要になります (RapidXML が文字列を参照している間は、その文字列を有効に保つ必要があります)。

RapidXML の DOM は必要最低限​​の機能しかありません。文字列値を取得できます。名前で属性を検索できます。それだけです。属性を他の値 (数値、日付など) に変換する便利な関数はありません。取得できるのは文字列だけです。

RapidXML のもう 1 つの欠点は、 XML の記述が面倒だということです。DOM を構築するには、文字列名のメモリ割り当てを明示的にたくさん行う必要があります。一種の文字列バッファは提供されますが、それでもユーザー側で多くの明示的な作業が必要になります。確かに機能的ですが、使用するのは面倒です。

MIT ライセンスを使用します。依存関係のないヘッダーのみのライブラリです。

パフォーマンスは気にしているが、それほどではない

はい、パフォーマンスは重要です。しかし、もう少しシンプルなものが必要かもしれません。より多くの Unicode を処理できるものや、ユーザーによるメモリ管理をそれほど必要としないものかもしれません。パフォーマンスは依然として重要ですが、もう少し直接的でないものが必要です。

あなたが選択しました:

プギXML

歴史的に、これは RapidXML のインスピレーションとなりました。しかし、2 つのプロジェクトは分岐し、Pugi はより多くの機能を提供するのに対し、RapidXML は完全に速度に重点を置いています。

PugiXML は Unicode 変換サポートを提供しているため、UTF-16 ドキュメントがあり、それを UTF-8 として読みたい場合は、Pugi が対応します。必要な場合は、XPath 1.0 実装も用意されています。

しかし、Pugi はそれでもかなり高速です。RapidXML と同様に依存関係はなく、MIT ライセンスの下で配布されています。

巨大な文書を読む

ギガバイト単位のサイズのドキュメントを読み取る必要があります。おそらく、他のプロセスによって入力された標準入力からドキュメントを取得しているのでしょう。あるいは、巨大なファイルからドキュメントを読み取っているのでしょう。あるいは、何でもいいのです。重要なのは、処理するためにファイル全体を一度にメモリに読み込まなくてもよいということです。

あなたが選択しました:

LibXML2

Xerces の SAX スタイル API はこの用途で機能しますが、LibXML2 の方が扱いやすいため、ここにあります。SAX スタイル API はプッシュ API です。つまり、ストリームの解析を開始し、キャッチする必要があるイベントを発生させるだけです。コンテキスト、状態などを管理する必要があります。SAX スタイル API を読み取るコードは、予想以上に広範囲にわたります。

LibXML2 のxmlReaderオブジェクトはプル API です。次の XML ノードまたは要素に移動するように要求しても、指示は出ません。これにより、必要に応じてコンテキストを保存し、多数のコールバックよりもコード内ではるかに読みやすい方法でさまざまなエンティティを処理できます。

代替案

外国人

Expat は、プル パーサー API を使用する有名な C++ パーサーです。James Clark によって作成されました。

現在のステータスはアクティブです。最新バージョンは 2.2.9 で、2019 年 9 月 25 日にリリースされました。

ラマXML

これは StAX スタイルの API の実装です。LibXML2 のパーサーに似たプル パーサーですxmlReader

しかし、2005 年以降は更新されていません。つまり、再度、買主は自己責任です。

XPath サポート

XPath は、XML ツリー内の要素をクエリするためのシステムです。標準化された構文を使用して、共通のプロパティによって要素または要素のコレクションに効果的に名前を付ける便利な方法です。多くの XML ライブラリが XPath をサポートしています。

ここでは実質的に 3 つの選択肢があります。

  • LibXML2 : XPath 1.0 を完全にサポートします。繰り返しますが、これは C API なので、それが気になる場合は代替手段があります。
  • PugiXML : XPath 1.0 もサポートされています。上記のように、LibXML2 よりも C++ API に近いため、より使いやすいかもしれません。
  • TinyXML : XPathのサポートはありませんが、タイニーXPathそれを提供するライブラリです。TinyXML はバージョン 2.0 への変換中であり、API が大幅に変更されているため、TinyXPath は新しい API では動作しない可能性があります。TinyXML 自体と同様に、TinyXPath は zLib ライセンスの下で配布されています。

ただ仕事をやり遂げる

つまり、XML の正確さは気にしないということです。パフォーマンスは問題ではありません。ストリーミングは無関係です。必要なのは、 XML をメモリに取り込み、それを再びディスクに戻すことができるものだけです。にするのは API です。

小さく、インストールが簡単で、使い方が簡単で、最終的な実行可能ファイルのサイズに関係ないほど小さい XML パーサーが必要です。

あなたが選択しました:

小さなXML

TinyXML をこのスロットに入れたのは、XML パーサーとしては非常に簡単に使用できるからです。確かに遅いですが、シンプルでわかりやすいです。属性の変換などに便利な関数がたくさんあります。

TinyXML では、XML の記述は問題ありません。newいくつかのオブジェクトを作成して、それらを結合し、ドキュメントを に送信するだけstd::ostreamで、すべてが完了します。

また、TinyXML を中心に構築されたエコシステムもあり、よりイテレータフレンドリーな API と、その上に重ねられた XPath 1.0 実装も備えています。

TinyXML は zLib ライセンスを使用します。これは、名前は異なりますが、MIT ライセンスとほぼ同じです。

おすすめ記事