15

申し訳ありませんが、以前に同じトピックについて質問しましたが、私の問題はそこに記載されている別の側面に関するものです (ブーストを反復する方法... )。

次のコードを見てください。

#include <iostream>
#include <string>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/algorithm/string/trim.hpp>
int main(int argc, char** argv) {
     using boost::property_tree::ptree;
     ptree pt;
     read_xml("try.xml", pt);
     ptree::const_iterator end = pt.end();
     for (ptree::const_iterator it = pt.begin(); it != end; it++)
           std::cout << "Here " << it->? << std::endl;
}

さて、私が言及した質問で言われたようにproperty_tree、Boostでイテレータを使用する可能性がありますが、それがどのタイプで、どのメソッドまたはプロパティを使用できるかわかりません。

ええと、ptree(必要に応じて) 再度ブラウズするには、別の xml 階層または別の xml 階層を表す何かである必要があると思いますが、これに関するドキュメントは非常に悪いです。理由はわかりませんが、ブーストのドキュメントでは、ノードをブラウズするためのマクロについて何か良いものを見つけることができませんが、このアプローチは本当に避けたいものです。

ここで私の質問に行きます: でイテレーターを取得したら、ptreeノード名、値、パラメーター (xml ファイル内のノード) にアクセスするにはどうすればよいですか? ありがとうございました

4

3 に答える 3

19

完全なツリーを印刷:

void print(boost::property_tree::ptree const& pt)
{
    using boost::property_tree::ptree;
    ptree::const_iterator end = pt.end();
    for (ptree::const_iterator it = pt.begin(); it != end; ++it) {
        std::cout << it->first << ": " << it->second.get_value<std::string>() << std::endl;
        print(it->second);
    }
}
于 2011-01-04T20:51:41.340 に答える
18

Andryに同意し、property_treeのドキュメントは少なくとも非常に最小限であると思います。異なる設定で同一のオブジェクトをロードするためにptreeが必要でしたが、イテレーターが何を反復するか、どのタイプを返すか、オブジェクトレベルに留まるかどうか、またはすべてのノードをBFSのように通過するかどうかを判断するのに苦労しました。最後に、次のようなケースでコードを機能させることができました。

設定ファイル:

<object1>
    <enable>true</enable>
    <label>hello</label>
</object1>
<object2>
    <enable>false</enable>
    <label>goodbye</label>
</object2>

まず、オブジェクトのコンストラクターを追加しました。これは、ptreeで初期化できます。get()の失敗時の例外を防ぐために、デフォルトのオプションでgetを使用していることに注意してください。

object::object(const boost::property_tree::ptree &pt_)
{
    enable = pt_.get<bool>("enable", true); // usage is: get<type>(path, default)
    label  = pt_.get<std::string>("label", "empty");
}

最後に、次のコードは両方のオブジェクトをロードし、それらをマップに配置します。

std::map<std::string, my_object> objects_map;

// parse settings file and add loggers
if(filesystem::exists(logger_settings_file))
{
    boost::property_tree::ptree pt;

    read_xml(logger_settings_file, pt);
    BOOST_FOREACH(boost::property_tree::ptree::value_type &v, pt)
    {
        objects_map[v.first] = my_object(v.second);
    }
}

だから、私自身の質問に答えるために:

  • イテレータは、下位レベルに下がることなく、設定ファイルを反復処理します。上記のコードを実行すると、ループが2回繰り返されることがわかります。XMLファイル内のオブジェクトごとに1回です。
  • イテレータは、ペアに似たvalue_typeオブジェクトを返し、firstsecondアクセサを持ちます。v.firstは親ノード(私の場合は「object1」、「object2」)を保持するstd :: stringでv.secondありboost::property_tree::ptree、オブジェクトのフィールドを解析するために使用できる、です。
于 2011-01-23T18:48:11.790 に答える
0

入力プロパティ ファイルに関する予備知識が必要です。

Boost プロパティ ツリーは、一般的なドキュメント パーサーではありません。解析を行い、データへのアクセスを許可しますが、手動で見つける必要があります。

ドキュメント全体をナビゲートする方法があるかどうかはわかりませんが、独自のファイルのプロパティのみが必要な場合は、非常に単純なコードで実行できます。

ブーストのドキュメントから:

1) 投げるバージョン (get):

ptree pt;
/* ... */
float v = pt.get<float>("a.path.to.float.value");

2) デフォルト値のバージョン (get):

ptree pt;
/* ... */
float v = pt.get("a.path.to.float.value", -1.f);

3) オプションのバージョン (get_optional):

ptree pt;
/* ... */
boost::optional<float> v = pt.get_optional<float>("a.path.to.float.value");
于 2011-01-04T20:26:55.360 に答える