获取标签的子标签详细信息[BOOST PORPERTY_TREE XML]
Get SubTag details of Tag [Boost Porperty_tree XML]
我正在尝试获取"子章"标签的详细信息。我不知道如何在标签中获取信息。
我的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'
相关文章:
- C 和 C++ 中开关语句的案例标签的常量值,但显示不同的行为
- 如何正确指定 goto 语句的标签?
- 使用g++静态初始化带有命名标签的嵌套C++结构
- 通过水平滚动条更改标签
- 从 QFontDatabase 设置 QFont 将所有标签设置为等宽字体?Qt C++
- 使用 boost::p roperty_tree::p tree 如何获取特定键的值
- 在C++中存储要输入的标签列表
- 如何在等效列表中查找最小的连接标签
- 标签检测鼠标单击 c++
- 无法将行编辑中的文本打印到 Qt C++ 中的标签
- 如何根据C++中的标签运行特定函数?
- C++ Expat 仅打印元素的第一个字母和标签中的数据
- 默认标签显然在 switch 语句中不起作用
- 在 gcc/clang (C++) 中获取函数范围之外的标签地址
- 在"printf"中使用标签"h"或"hh"是否涉及未定义的
- GTK 3 C++按钮中带有标签的图标
- 如何使QLineSeries/QXYSeries仅显示一个点标签
- SFINAE和标签调度之间的差异
- 如何在主窗口标签的对话框中显示QLineEdit的输入
- Qt - 将空指针(原始数据)转换为 QImage 并将其显示在标签上