获取标签的子标签详细信息[BOOST PORPERTY_TREE XML]

Get SubTag details of Tag [Boost Porperty_tree XML]

本文关键字:标签 TREE PORPERTY XML 详细信息 获取 BOOST      更新时间:2023-10-16

我正在尝试获取"子章"标签的详细信息。我不知道如何在标签中获取信息。

我的XML看起来像这样:

<xml>
    <chapter>
        <name>First Chapter</name>
        <link>xyz1</link>
        <chapter>
            <name>First Sub-Chapter</name>
            <link>xyz2</link>
        </chapter>
    </chapter>
</xml>

现在我想获取第二章标签的信息...我的C 看起来像这样:

boost::property_tree::ptree pt;
boost::property_tree::xml_parser::read_xml("file.xml", pt, boost::property_tree::xml_parser::trim_whitespace );
BOOST_FOREACH(const boost::property_tree::ptree::value_type& node, pt.get_child("xml"))
{
    if( node.first == "chapter" )
    {
        chapter chp;
        chp.name = node.second.get<std::string>("name");
        chp.link = node.second.get<std::string>("link");
        //boost::property_tree::ptree::value_type test = node.second.get<boost::property_tree::ptree::value_type>("chapter");
        //chapter chp2;
        //chp2.name = test.second.get<std::string>("name");
        //chp2.link = test.second.get<std::string>("link");
        //chp.sub_chapters.push_back( chp2 );
        m_chapters.push_back( chp );
    }
}

我尝试了它,就像您可以看到的评论行一样。我还尝试使用另一个boost_foreach。有办法达到我的目标吗?

感谢您的帮助!etchz!

我会使用简单的递归查找算法:

template <typename Tree, typename Out>
Out find_all_chapters(Tree const& pt, Out out) {
    using namespace boost::property_tree;
    BOOST_FOREACH(typename Tree::value_type const& ch, pt) {
        if (ch.first == "chapter") {
            *out++ = chapter { 
                    ch.second.template get<std::string>("name"),
                    ch.second.template get<std::string>("link")
                };
            out = find_all_chapters(ch.second, out);
        }
    }
    return out;
}

这是假设嵌套的章节总是出现在其他章节内(否则将递归调用移出if()条件块。)

您可以像

一样使用它
int main() {
    boost::property_tree::ptree pt;
    boost::property_tree::xml_parser::read_xml("file.xml", pt, boost::property_tree::xml_parser::trim_whitespace );
    std::vector<chapter> m_chapters;
    find_all_chapters(pt.get_child("xml"), back_inserter(m_chapters));
    for (auto& ch : m_chapters)
        std::cout << "Chapter '" << ch.name << "', link: '" << ch.link << "'n";
}

它打印

Chapter 'First Chapter', link: 'xyz1'
Chapter 'First Sub-Chapter', link: 'xyz2'

完整列表

活在coliru

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/foreach.hpp>
#include <iostream>
struct chapter {
    std::string name, link;
};
template <typename Tree, typename Out>
Out find_all_chapters(Tree const& pt, Out out) {
    using namespace boost::property_tree;
    BOOST_FOREACH(typename Tree::value_type const& ch, pt) {
        if (ch.first == "chapter") {
            *out++ = chapter { 
                    ch.second.template get<std::string>("name"),
                    ch.second.template get<std::string>("link")
                };
            out = find_all_chapters(ch.second, out);
        }
    }
    return out;
}
int main() {
    boost::property_tree::ptree pt;
    boost::property_tree::xml_parser::read_xml("file.xml", pt, boost::property_tree::xml_parser::trim_whitespace );
    std::vector<chapter> m_chapters;
    find_all_chapters(pt.get_child("xml"), back_inserter(m_chapters));
    for (auto& ch : m_chapters)
        std::cout << "Chapter '" << ch.name << "', link: '" << ch.link << "'n";
}

更新

在评论中,这就是我的做法:

活在coliru

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/foreach.hpp>
#include <iostream>
struct chapter {
    std::string name, link;
    std::vector<chapter> sub_chapters;
};
void find_all_chapters(boost::property_tree::ptree const& pt, chapter& into) {
    for(auto& ch : pt) {
        if (ch.first == "chapter") {
            into.sub_chapters.push_back({ 
                    ch.second.template get<std::string>("name"),
                    ch.second.template get<std::string>("link"),
                    {}
                });
            find_all_chapters(ch.second, into.sub_chapters.back());
        }
    }
}
void print(chapter const& book_or_chapter, std::string const& indent = "") 
{
    for (auto& ch : book_or_chapter.sub_chapters) {
        std::cout << indent << " - Chapter '" << ch.name << "', link: '" << ch.link << "'n";
        print(ch, "    " + indent);
    }
}
int main() {
    boost::property_tree::ptree pt;
    boost::property_tree::xml_parser::read_xml(std::cin, pt, boost::property_tree::xml_parser::trim_whitespace );
    chapter book;
    find_all_chapters(pt.get_child("xml"), book);
    print(book);
}

使用输入xml喜欢

<xml>
    <chapter>
        <name>First Chapter</name>
        <link>xyz1</link>
        <chapter>
            <name>First Sub-Chapter</name>
            <link>xyz2</link>
            <chapter>
                <name>Sub Sub</name>
                <link>xyz3</link>
                <chapter>
                    <name>Sub Sub Sib</name>
                    <link>xyz4</link>
                </chapter>
            </chapter>
        </chapter>
    </chapter>
    <chapter>
        <name>Second Chapter</name>
        <link>abc1</link>
        <chapter>
            <name>First Sub-Chapter</name>
            <link>abc2</link>
        </chapter>
    </chapter>
</xml>

打印

 - Chapter 'First Chapter', link: 'xyz1'
     - Chapter 'First Sub-Chapter', link: 'xyz2'
         - Chapter 'Sub Sub', link: 'xyz3'
             - Chapter 'Sub Sub Sib', link: 'xyz4'
 - Chapter 'Second Chapter', link: 'abc1'
     - Chapter 'First Sub-Chapter', link: 'abc2'