C ++ではどのXMLパーサーを使用すればよいですか?[閉まっている]


344

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

注:これは、C ++-FAQスタイルの決定的な質問であることを意図しています。そう、それは他のものの複製です。他の質問はもう少し具体的なものを求める傾向があったため、私はそれらの他の質問を単に適切に使用しませんでした。この質問はより一般的です。


私はtiCpp code.google.com/p/ticppが好きですが、ドキュメントは(まだ?)

回答:


679

標準ライブラリコンテナの場合と同様に、使用するライブラリはニーズによって異なります。便利なフローチャートは次のとおりです。

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

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

完全なXMLコンプライアンスが必要

OK、XMLを処理する必要があります。おもちゃのXMLではなく、実際の XML。低水準で解析しやすいビットだけでなく、XML仕様のすべてを読み書きできる必要があります。名前空間、DocType、エンティティ置換、作業が必要です。W3C XML仕様全体。

次の質問は次のとおりです。APIはDOMまたはSAXに準拠する必要がありますか?

正確なDOMやSAXへの準拠が必要

OK、それであなたは本当にAPIがDOMやSAXである必要があります。SAXスタイルのプッシュパーサーやDOMスタイルの保持パーサーだけではありません。それはしなければならない C ++が可能になる程度に、実際のDOMやSAX実際、あること。

あなたが選択しました:

Xerces

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

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

DOMやSAXの適合性を気にしません

あなたが選択しました:

LibXML2

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

iconvへの依存関係はありますが、その依存関係なしで構成できます。これは、解析できる可能なテキストエンコーディングのセットがより限定されることを意味します。

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

XMLに完全に準拠する必要はありません

OK、完全なXMLコンプライアンスは問題ではありません。XML文書は完全に管理されているか、XMLの「基本サブセット」を使用することが保証されています。名前空間やエンティティなどはありません。

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

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

アプリケーションは、XMLを取得して、この変換が発生する可能性がある限りの速さでXMLをC ++データ構造に変換する必要があります。

あなたが選択しました:

RapidXML

このXMLパーサーは、まさにそのとおりです。高速なXMLです。ファイルをメモリにプルすることさえ扱いません。それがどのように起こるかはあなた次第です。それが処理するのは、アクセスできる一連のC ++データ構造に解析することです。そして、バイト単位でファイルをスキャンするのと同じくらい速くこれを行います。

もちろん、無料のランチなどはありません。XML仕様を気にしないほとんどのXMLパーサーと同様に、Rapid XMLは名前空間、DocType、エンティティ(文字エンティティと6つの基本的なXMLエンティティを除く)などに影響を与えません。つまり、基本的にはノード、要素、属性などです。

また、DOMスタイルのパーサーです。したがって、すべてのテキストを読み込む必要があります。ただし、何もしないのは、そのテキストを(通常は)コピーすることです。RapidXMLがほとんどの速度を得る方法は、文字列をインプレースで参照することです。これには、ユーザー側でより多くのメモリ管理が必要です(RapidXMLが文字列を見ている間、その文字列を存続させる必要があります)。

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

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

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

私はパフォーマンスに関心がありますが、それほど重要ではありません

はい、パフォーマンスはあなたにとって重要です。しかし、多分あなたはもう少し必要最低限​​のものが必要です。たぶん、より多くのUnicodeを処理できるものか、それほどユーザー制御のメモリ管理を必要としないものでしょう。パフォーマンスは依然として重要ですが、少し直接的なものではありません。

あなたが選択しました:

PugiXML

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

PugiXMLはUnicode変換サポートを提供しているため、周りにいくつかのUTF-16ドキュメントがあり、それらをUTF-8として読みたい場合は、Pugiが提供します。そのようなものが必要な場合は、XPath 1.0実装も含まれます。

しかし、プーギはまだかなり速いです。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-09-25)にリリースされました。

LlamaXML

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

しかし、それは2005年以来更新されていません。繰り返しますが、Caveat Emptorです。

XPathサポート

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

ここには効果的に3つの選択肢があります。

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

仕事を終わらせる

したがって、XMLの正確さは気にしません。パフォーマンスは問題ではありません。ストリーミングは無関係です。あなたが望むすべてがある何かメモリーにXMLを取得し、あなたが再び戻ってディスクにそれを固執することができます。何あなたが気にすることはAPIです。

小さく、インストールが簡単で、使用が簡単で、最終的な実行可能ファイルのサイズとは無関係な大きさのXMLパーサーが必要です。

あなたが選択しました:

TinyXML

TinyXMLをこのスロットに配置したのは、XMLパーサーが取得するのと同じくらい簡単に使用できるためです。はい、遅いですが、それは単純で明白です。属性変換などの便利な機能がたくさんあります。

TinyXMLではXMLの記述は問題ありません。あなたはnewいくつかのオブジェクトを持ち上げ、それらを一緒に接続し、ドキュメントをに送信するstd::ostreamと、みんなが幸せになります。

また、TinyXMLを中心に構築されたエコシステムの一部があり、よりイテレータにやさしいAPIがあり、さらにその上にXPath 1.0実装があります。

TinyXMLはzLibライセンスを使用します。これは多かれ少なかれ、MITライセンスとは異なる名前です。


6
これは、コピーと貼り付けに少し似ています。ソースドキュメントをリンクできますか?
ジョエル

28
@ジョエル:かなり長い投稿で自分の質問に誰かが答えるとき、それは彼らがジェフのアドバイスの精神に従っているためです-特に、まあまあの質問のように見えるものはしばしば良い答えができる前に閉じることができるためですその人がその場で答えを書いている場合、投稿されます。質問をする前に時間をかけて回答を準備することで、:)ニコルは、近い将来、重複する質問の優れた候補者を私たち全員に提供しています。
サルノルド

28
@ジョエル:私はできません。Notepad ++でコピーした一時的なドキュメントにすぎません。保存しなかったので、リンクできません;)
Nicol Bolas

6
TinyXMLの新しいバージョンについて言及する価値があるかもしれません:TinyXML-2は、TinyXML-1と同様のAPIと同じリッチテストケースを使用します。しかし、パーサーの実装は完全に書き直されて、ゲームでの使用により適したものになっています。メモリ使用量が少なく、高速で、メモリ割り当てをほとんど使用しません。
johnbakers 2013

6
私はこの質問と回答が好きですが、あまりにもUni​​xに偏っています。MSXMLとXmlLiteについての言及はありませんか?マルチパレットの移植性がそれらを除外する理由である場合、これは質問と回答で明確に述べられるべきです。(そうでなければ、一部の人々は、例えばWindowsのみのプロジェクトにLibxml2を選択することになるかもしれません。それは簡単に回避できたかもしれない頭痛を求めています。)
Scrontch

17

XMLデータバインディングと呼ばれる、XMLを処理する別の方法があります。特に、たとえばXMLスキーマなど、XML語彙の正式な仕様がすでにある場合。

XMLデータバインディングを使用すると、XMLの解析やシリアル化を実際に行わなくてもXMLを使用できます。データバインディングコンパイラはすべての低レベルコードを自動生成し、解析されたデータをアプリケーションドメインに対応するC ++クラスとして表示します。次に、文字列を比較してテキストを解析する代わりに、関数を呼び出してC ++型(int、doubleなど)を操作することで、このデータを操作します(これは、DOMやSAXなどの低レベルのXMLアクセスAPIで行うことです)。

たとえば、私が作成したオープンソースのXMLデータバインディング実装であるCodeSynthesis XSDを参照してください。 軽量で依存関係のないバージョンについては、CodeSynthesis XSD / eを参照してください


13
私は投稿を気にしませんが、SOポリシーでは、あなたが書いたものを提案する場合は、完全な開示のために、あなたが書いたことを述べる必要があると述べています。
Nicol Bolas

@Nicol私はそれを答えに編集しました。
JBentley 2013年

おそらくこのリストは役に立つでしょうが、そのリストの作成者が誰なのかを見つけることができませんでした(公開しないと、説明と評価が意味があるかどうかわかりません)。おそらく、パブリックドメインにあり、テストとレポートに使用されたいくつかのデータバインディングツールをリストするW3Cデータバインディングワーキンググループを見ることができます(完全な開示:私はCodeSynthesisとは関係がなく、W3Cにリストされているgsoapを助けました)ツール)。
Alex RE

1

Expatに関するもう1つの注意:組み込みシステムの動作を確認する価値があります。ただし、Webで見つけられる可能性が高いドキュメントは古く、間違っています。ソースコードには実際にはかなり完全な関数レベルのコメントがありますが、それらを理解するにはいくらか熟読する必要があります。



0

じゃあね。リストのどれも私のニーズを満たしていなかったので、私は新しいものを作成しました。

利点:

  1. 低レベルのプルパーサーストリーミングAPI(Java StAXのような
  2. サポートされる例外とRTTIモード
  3. メモリ使用量の制限、大きなファイルのサポート(100 mib XMarkファイルでテスト済み、速度はハードウェアに依存)
  4. UNICODEサポート、および入力ソースエンコーディングの自動検出
  5. 構造/ POCOに読み込むための高レベルAPI
  6. XML構造(属性とネストタグ)をサポートする構造/ POCOからXSDを作成および生成するためのメタプログラミングAPI (XSD生成にはRTTIが必要ですが、デバッグ時にのみ使用して1回のみ行うことができます)
  7. C ++ 11-GCCおよびVC ++ 15以降

短所:

  1. DTDおよびXSD検証はまだ提供されていません
  2. 進行中のHTTP / HTTPSによるXML / XSDの取得、まだ完了していません
  3. 新しいライブラリ

プロジェクトホーム


1
ベンチマークを追加できますか?
Vadim Peretokin

-1

保護されたグローブ、株式会社我々は、使用rapidxmlを。他のすべてを試しましたが、rapidxmlが私たちにとって最良の選択のようです。

次に例を示します。

 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);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.