C++ 遍历不包含标记名的PTree子级
我想知道是否有一种方法可以通过迭代父节点的向量来获取子节点中的数据。我有一个XML文件,我计划经常更改它,因此硬编码属性名称是我希望避免的事情。因此,我希望通过使用C++ 遍历不包含标记名的PTree子级,c++,xml,visual-studio,boost,ptree,C++,Xml,Visual Studio,Boost,Ptree,我想知道是否有一种方法可以通过迭代父节点的向量来获取子节点中的数据。我有一个XML文件,我计划经常更改它,因此硬编码属性名称是我希望避免的事情。因此,我希望通过使用pt.get\u child(myparentNodes)提取子节点中的数据,而不说明节点的标记名。这是我的主菜 非常感谢您的帮助 vector<string> parentNodes; ptree pt; ifstream fileName("myxml"); read_xml(fileName, p
pt.get\u child(myparentNodes)
提取子节点中的数据,而不说明节点的标记名。这是我的主菜
非常感谢您的帮助
vector<string> parentNodes;
ptree pt;
ifstream fileName("myxml");
read_xml(fileName, pt);
for(const ptree::value_type &parent : pt)
{
cout << parent.first << std::endl;
parentNodes.push_back(parent.first);
}
for(int i=0; i<parentNodes.size();i++)
{
BOOST_FOREACH(boost::property_tree::ptree::value_type const &node,pt.get_child(parentNodes[i]))
/* I'm having trouble properly accessing the children nodes here */
向量父节点;
ptree-pt;
ifstream文件名(“myxml”);
读取xml(文件名,pt);
for(const ptree::value_type&parent:pt)
{
cout在您的代码片段中(稍微清理):
当然,使用Range for更容易:
for (auto const& name : parentNodes) {
auto& parent = pt.get_child(name);
for (auto const& child : parent) {
std::cout << child.first << std::endl;
}
}
仍然在做同样的事情
概括
您说过要将此设置为通用。但是,假设父/子关系的两层层次结构在我看来不是“通用的”。我将您链接到一些显示通用遍历的示例(例如,在整个树中查找模式),例如,该示例中的一个函数:
#include <boost/property_tree/xml_parser.hpp>
#include <iostream>
using boost::property_tree::ptree;
static auto settings = boost::property_tree::xml_writer_make_settings<std::string>(' ', 4);
template <typename Out>
Out enumerate_nodes(ptree const& pt, ptree::path_type path, Out out) {
if (path.empty())
return out;
if (path.single()) {
auto name = path.reduce();
for (auto& child : pt) {
if (child.first == name)
*out++ = child.second;
}
} else {
auto head = path.reduce();
for (auto& child : pt) {
if (head == "*" || child.first == head) {
out = enumerate_nodes(child.second, path, out);
}
}
}
return out;
}
int main() {
std::ifstream fileName("input.xml");
ptree pt;
read_xml(fileName, pt);
for (auto const& [name, node] : pt) {
std::cout << name << std::endl;
for (auto const& child : node)
std::cout << child.first << std::endl;
}
std::vector<std::reference_wrapper<ptree const>> matched;
enumerate_nodes(pt, "root.parent2.child3", back_inserter(matched));
for (ptree const& match : matched)
std::cout << "Matched: " << match.get_value<std::string>() << "\n";
}
印刷品
root
parent1
parent2
parent3
parent4
Matched: parent2/child3
for (auto const& parent : pt) {
std::cout << parent.first << std::endl;
auto& node = parent.second;
for (auto const& child : node) {
std::cout << child.first << std::endl;
}
}
for (auto const& [name, node] : pt) {
std::cout << name << std::endl;
for (auto const& child : node) {
std::cout << child.first << std::endl;
}
}
#include <boost/property_tree/xml_parser.hpp>
#include <iostream>
using boost::property_tree::ptree;
static auto settings = boost::property_tree::xml_writer_make_settings<std::string>(' ', 4);
template <typename Out>
Out enumerate_nodes(ptree const& pt, ptree::path_type path, Out out) {
if (path.empty())
return out;
if (path.single()) {
auto name = path.reduce();
for (auto& child : pt) {
if (child.first == name)
*out++ = child.second;
}
} else {
auto head = path.reduce();
for (auto& child : pt) {
if (head == "*" || child.first == head) {
out = enumerate_nodes(child.second, path, out);
}
}
}
return out;
}
int main() {
std::ifstream fileName("input.xml");
ptree pt;
read_xml(fileName, pt);
for (auto const& [name, node] : pt) {
std::cout << name << std::endl;
for (auto const& child : node)
std::cout << child.first << std::endl;
}
std::vector<std::reference_wrapper<ptree const>> matched;
enumerate_nodes(pt, "root.parent2.child3", back_inserter(matched));
for (ptree const& match : matched)
std::cout << "Matched: " << match.get_value<std::string>() << "\n";
}
root
parent1
parent2
parent3
parent4
Matched: parent2/child3