web-dev-qa-db-ja.com

C ++でxmlを生成する最も簡単な方法は何ですか?

ブーストシリアル化を使用しましたが、特定のスキーマに準拠するxmlを生成できないようです。目的は、クラスの状態を永続化することだけだったようです。

プラットフォーム:Linux

NOT parse xmlを生成するために何を使用しますか?

これまでのところ、Foredeckerが自分で生成するというルートをたどっています。これは大きなドキュメントではありませんが、正しく生成するための適切なライブラリを見つけるのにそれほど問題はないはずです。

ブーストに関しては、ノード名を設定し、ノードに属性を設定し、追加する必要がないので、それに伴う余分ながらくたをすべて取り除くことができます。私のドキュメントをそのクラスに戻します。

16
eyberg

XML異端者と宣言する人もいるかもしれませんが、効果的な方法の1つは、お気に入りの文字列出力ツール(印刷、出力ストリームなど)でXMLを生成することです。これは、バッファーまたはファイルに移動できます。

保存したら、出荷する前にスキーマで検証する必要があります。

私たちのプロジェクトの1つには、開始/終了タグと属性を管理するための非常に単純なテンプレートのセットがあります。これらにはそれぞれストリーム出力演算子があります。これにより、ソースXMLの生成とデバッグが非常に簡単になります。これにより、XML生成コードの構造がXML自体に非常によく似たものになります。

これの利点の1つは、ファイルにストリーミングする場合に大量のXMLを効率的に生成できることです。検証コストは後で支払います(おそらく、費用のかかる操作の場合はより良い時期に)。

この手法の欠点は、基本的に出力のみであるということです。 XMLを動的に作成して消費するのには適していません。

13
Foredecker

私は最近、特にXMLコードを生成するための一連のXMLライブラリを確認しました。

エグゼクティブサマリー:私は TinyXML ++ を選択しました。

TinyXML ++はまともなC++構文を持ち、成熟した TinyXML Cライブラリ上に構築されており、フリーでオープンソース(MITライセンス)で小規模です。要するに、それは仕事を素早く終わらせるのに役立ちます。簡単なスニペットは次のとおりです。

Document doc;
Node* root(doc.InsertEndChild(Element("RootNode")));
Element measurements("measurements");
Element tbr("TotalBytesReceived",  12);
measurements.InsertEndChild(tbr);
root->InsertEndChild(measurements);

生成するもの:

<RootNode>
    <measurements>
        <TotalBytesReceived>12</TotalBytesReceived>
    </measurements>
</RootNode>

とても満足しています。

私は他の多くをレビューしました。ここにいくつかのより良い候補があります:

Xerces :キングパパ。 everything(特に Xalan と組み合わせた場合)を実行しますが、重量があり、ユーザーにメモリ管理を強制します。

RapidXML :解析には最適です(in-situパーサーであり、fast)ですが、ノードをに追加するため、生成には適していませんDOMにはメモリ管理が必要です。

Boost.XML (提案):見た目素晴らしい-強力で優れたC++構文。ただし、まだレビュープロセスを経ておらず、サポートされておらず、インターフェースが変更される可能性があります。とにかくほとんどそれを使用しました。 Boostへの受け入れを楽しみにしています。

Libxml++ ):とても良い;強力でまともな構文。しかし、生成XMLだけで、glibmmライブラリ(ustring用)に関連付けられている場合は、かなり大きくなります。もし私たちがLinux上でonlyだったら(あなたのように?)私は真剣に検討したいと思います。

XiMOL :一意のストリームベースのライブラリ。これは私たちのニーズには少し単純すぎましたが、基本的なXML生成には非常に便利です。ストリームの構文は非常に適切です。

うまくいけば、そこにいくつかの有用な何かがあります!

49
MattyT

Boost.PropertyTreeは、XMLを生成するための素晴らしく簡単な方法です-特にBoostをすでに使用している場合はそうです。

以下は完全なサンプルプログラムです。

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>

using boost::property_tree::ptree;
using boost::property_tree::write_xml;
using boost::property_tree::xml_writer_settings;

int wmain(int argc, wchar_t* argv[]) {
    char* titles[] = {"And Then There Were None", "Android Games", "The Lord of the Rings"};

    ptree tree;
    tree.add("library.<xmlattr>.version", "1.0");
    for (int i = 0; i < 3; i++) {
        ptree& book = tree.add("library.books.book", "");
        book.add("title", titles[i]);
        book.add("<xmlattr>.id", i);
        book.add("pageCount", (i+1) * 234);
    }

    // Note that starting with Boost 1.56, the template argument must be std::string
    // instead of char
    write_xml("C:\\Users\\Daniel\\Desktop\\test.xml", tree,
        std::locale(),
        xml_writer_settings<char>(' ', 4));

    return 0;
}

結果のXMLは次のようになります。

<?xml version="1.0" encoding="utf-8"?>
<library version="1.0">
    <books>
        <book id="0">
            <title>And Then There Were None</title>
            <pageCount>234</pageCount>
        </book>
        <book id="1">
            <title>Android Games</title>
            <pageCount>468</pageCount>
        </book>
        <book id="2">
            <title>The Lord of the Rings</title>
            <pageCount>702</pageCount>
        </book>
    </books>
</library>

特に優れている点の1つは、ドットで区切られたパスです。これにより、途中ですべてのノードを暗黙的に作成できます。 documentation はかなり貧弱ですが、ptree.hppと一緒に使用すると、どのように機能するかがわかります。

9
Daniel Wolf

私はtinyXml ++を使用しており、上記のようにxmlを非常に簡単に作成できます。また、1つのコマンドでファイルに保存しますが、バッファーに保存する方法がわかりません。

0
Lodle

どのプラットフォーム? MSXMLはWindowsのオプションです。 CMarkup は別の良い選択です。 .NETがオプションの場合、優れたXMLサポートがあります。

0
Serge Wautier

私は実際にこれを行うためにブーストシリアル化を試していませんが、私が理解しているように、オプションを慎重に選択すると、スキーマにさまざまなオプションを設定できます(ポインターのフライウェイトの防止や特定のタイプの要素名の設定など) )

0
coppro