我刚刚发现了Boost :: property_tree,这似乎是我遇到的完美答案。我写了一个小型测试程序来从XML文件中提取特定数据。我使用文档中提供的示例作为指导。 XML文件:test.xml:

<section>
    <GROUP>
        <g_name>ABC</g_name>
        <fields>
            <row>
                <name>A</name>
                <datatype>string</datatype>
                <field_size>6</field_size>
                <value>ABC</value>
            </row>
            <row>
                <name>B</name>
                <datatype>integer</datatype>
                <field_size>5</field_size>
                <value>00107</value>
            </row>
            <row>
                <name>C</name>
                <datatype>string</datatype>
                <field_size>20</field_size>
                <value>LOTS OF LETTERS     </value>
            </row>
        </fields>
    </GROUP>
    <GROUP>
        <g_name>CDE</g_name>
        <fields>
            <row>
                <name>A</name>
                <datatype>string</datatype>
                <field_size>6</field_size>
                <value>CDE</value>
            </row>
            <row>
                <name>B</name>
                <datatype>integer</datatype>
                <field_size>5</field_size>
                <value>00100</value>
            </row>
            <row>
                <name>F</name>
                <datatype>integer</datatype>
                <field_size>4</field_size>
                <value>1970</value>
            </row>
        </fields>
    </GROUP>
</section>
.

代码:

        using boost::property_tree::ptree;
        struct t_collection
        {
            ptree pt;
            void load(const std::string &filename);
            void print();
        };
        void t_collection::load(const std::string &filename)
        {
            read_xml(filename, pt);
        }
        void t_collection::print()
        {
                BOOST_FOREACH(ptree::value_type &v, pt.get_child("section.GROUP"))
BOOST_FOREACH(ptree::value_type &v, pt.get_child("section.GROUP"))
{
    printf("X: %s->", v.second.data().c_str());
    //prints X: ABC ->
    BOOST_FOREACH(ptree::value_type &w, pt.get_child("section.GROUP.fields.row"))
        printf("%s\n", w.second.data().c_str());
    //prints A, string, 6, ABC - that is good for first iteration but there should be 3 iterations here
}
//then prints X: and just "" and repeats the set from the first one 
        }
        int main()
        {
            try
            {
                t_collection t1;
                t1.load("test.xml");
                t1.print();
            }
            catch (std::exception &e)
            {
                std::cout << "Error: " << e.what() << "\n";
            }
            return 0;
        } 
.

注意:我正在尝试提取值(abc和内值,如 - string - 6 - abc,每个组 - 以及每组“行”,我将处理,然后在不同的情况下输出格式)。有关我尝试的东西,请参阅代码中的评论。
到目前为止,最好的结果是:(印刷中的内容():

BOOST_FOREACH(ptree::value_type &z, pt.get_child("section"))
    //BOOST_FOREACH(ptree::value_type &v, pt.get_child("section.GROUP"))
        {
            printf("X: %s->", pt.get<std::string>("section.GROUP.g_mame", "default").c_str());
            //prints X: ABC ->
            BOOST_FOREACH(ptree::value_type &w, pt.get_child("section.GROUP.fields.row"))
            {
                printf("%s\n", pt.get<std::string>("section.GROUP.fields.row.name", "name").c_str());
                printf("%s\n", pt.get<std::string>("section.GROUP.fields.row.datatype", "type").c_str());
                printf("%s\n", pt.get<std::string>("section.GROUP.fields.row.field_size", "size").c_str());
                printf("%s\n", pt.get<std::string>("section.GROUP.fields.row.value", "value").c_str());
            }
        }
        //prints x: default->A, string, 6, ABC (3 times) then repeat identically
.

我无法从多个记录中获取数据!请帮忙,给我一个建议 - 我做错了什么?
谢谢。

有帮助吗?

解决方案

您在迭代中缺少一个级别。您需要迭代具有具有相同名称的多个子项的元素。

std::pair<ptree::const_assoc_iterator, ptree::const_assoc_iterator>
    r(pt.get_child("section").equal_range("GROUP"));

for (ptree::const_assoc_iterator i(r.first); i != r.second; ++i) {
    // Do something with each group.
}
. 如你下降树的那样重复。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top