Boost Property_Tree迭代器,如何处理它们?

发布于 2024-10-10 00:45:28 字数 1015 浏览 3 评论 0原文

抱歉,我之前问过关于同一主题的问题,但我的问题涉及那里描述的另一个方面(如何迭代提升...)。

看一下下面的代码:

#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;
}

嗯,正如我在提到的问题中被告知的那样,可以在 Boost 中的 property_tree 上使用迭代器,但我不知道它是什么类型,以及我可以使用哪些方法或属性。

好吧,我假设它必须是另一个 ptree 或代表要再次浏览的另一个 xml 层次结构的东西(如果我愿意),但有关此的文档非常糟糕。我不知道为什么,但在 boost 文档中我找不到任何好的东西,只是关于浏览节点的宏的东西,但这种方法是我真正想避免的一种方法。

所以在这里回答我的问题:在 ptree 上获取迭代器后,如何访问节点名称、值、参数(xml 文件中的节点)? 谢谢

I am sorry, I asked a question about the same topic before, but my problem concerns another aspect of the one described there (How to iterate a boost...).

Take a look at the following code:

#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;
}

Well, as I got told told in the question I mentioned, there is the possibility to use iterators on property_tree in Boost, but I do not know what type it is, and what methods or properties I can use.

Well, I assume that it must be another ptree or something representing another xml hierarchy to be browsed again (if I want) but documentation about this is very bad. I do not know why, but in boost docs I cannot find nothing good, just something about a macro to browse nodes, but this approach is one I would really like to avoid.

So getting to my question here: Once getting the iterator on a ptree, how can I access node name, value, parameters (a node in a xml file)?
Thankyou

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

红玫瑰 2024-10-17 00:45:28

打印完整的树:

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);
    }
}

print complete tree:

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);
    }
}
心意如水 2024-10-17 00:45:28

我同意 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);
    }
}

因此,回答我自己的问题:

  • 迭代器迭代设置文件而不下降到较低级别。运行上面的代码,您会发现循环迭代了两次 - XML 文件中的每个对象一次。
  • 迭代器返回一个类似于一对的 value_type 对象,并具有 firstsecond 访问器。 v.first 是一个 std::string ,保存父节点(在我的例子中为“object1”、“object2”),而 v.second 是一个 boost ::property_tree::ptree,可用于解析对象的字段。

I agree with Andry, and find the documentation of property_tree to be extremely minimal at the least. I needed ptree for loading identical objects with different settings, and had trouble figuring out what the iterator iterates over, what type it returns, and whether or not it will remain on the objects level, or go through every node BFS-like. Finally, I managed to get my code working for a case similar to the following:

settings file:

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

First, I added a constructor for my object, which can initialize on a ptree. Note that I'm using the get with default option, to prevent exception on failed get()'s:

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");
}

Finally the following code loads both objects, and places them in a map:

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);
    }
}

So, to answer my own questions:

  • The iterator iterates over the settings file without descending into lower levels. Running the above code you will find that the loop iterates twice - one time for each object in the XML file.
  • The iterator returns a value_type object which resembles a pair, and has the first and second accessors. v.first is an std::string holding the parent node (in my case "object1", "object2"), and v.second is a boost::property_tree::ptree, which can be used to parse the fields of the object.
回首观望 2024-10-17 00:45:28

您应该对输入属性文件有先验知识。

Boost 属性树不是通用的文档解析器。它将进行解析并提供对数据的访问,但必须手动找到它。

我不知道有什么方法可以导航整个文档,但如果您只需要自己文件的属性,则可以使用非常简单的代码来完成。

来自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");

You should have the prior knowledge on the input property file.

Boost property tree is not a general document parser. It will do parsing and give access to the data, but must locate it manually.

I don't know there are method to navigate whole document, but if you only need the properties of your own file you can do it with very simple code.

From the boost documentation:

1) The throwing version (get):

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

2) The default-value version (get):

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

3) The optional version (get_optional):

ptree pt;
/* ... */
boost::optional<float> v = pt.get_optional<float>("a.path.to.float.value");
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文