提升属性树:从一个节点中删除属性 [英] Boost Property Tree: Remove attribute from a node
问题描述
我有下面的XML文件:
I have the following XML file:
<?xml version="1.0" encoding="utf-8"?>
<gexf>
<graph>
<nodes>
<node id="0" label="0" start="0" end="25"/>
<node id="1" label="1" start="1"/>
<node id="2" label="2" start="2"/>
...
</nodes>
<edges>
<edge id="0" source="0" target="1" start="7" end="19"/>
<edge id="1" source="0" target="2" start="8" end="20"/>
...
</edges>
</graph>
</gexf>
我要删除启动
和结束
从边缘与源属性= 0
和目标=1
。
我试图做到这一点的方法是在以下code。假设XML文件被命名为 ptree_test.gexf
我读它,在树中找到正确的边缘,然后尝试使用删除
摆脱属性。
The way I've tried to do this is in the following code. Assuming the XML file is named ptree_test.gexf
I read it in, find the correct edge in the tree, and then attempt to use erase
to get rid of the attributes.
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <iostream>
using boost::property_tree::ptree;
int main(int argc, char *argv[]) {
ptree pt;
read_xml("ptree_test.gexf", pt);
// Now find edge (0, 1) and delete the start and end attributes
ptree edge;
int id1, id2;
id1 = 0;
id2 = 1;
for(auto &e : pt.get_child("gexf.graph.edges")) {
int s, t;
s = e.second.get<int>("<xmlattr>.source");
t = e.second.get<int>("<xmlattr>.target");
// Check if this is the correct edge
// Two checks because it can be reversed
if((id1 == s && id2 == t) || (id1 == t && id2 == s)) {
edge = e.second;
break;
}
}
for(auto & attr : edge.get_child("<xmlattr>")) {
if(attr.first == "end" || attr.first == "start") {
edge.erase(attr.first);
}
}
write_xml(std::cout, pt);
return 0;
}
这是行不通的。它不会删除该属性。事实上,如果我把它打印 edge.erase返回调试语句(attr.first)
它显示了 0
。
This does not work. It doesn't remove the attribute. In fact, if I put in a debug statement that prints the return of edge.erase(attr.first)
it shows 0
.
推荐答案
主要的问题是,你正在子树的副本,在这一行:
The main problem is that you are making a copy of the subtree in this line:
edge = e.second;
再修改,而不是的复制的原。后来,随着@NicolBolas说你需要一个迭代符为删除
。全code是这样的:
and then modifying that copy instead of the original. Later, as @NicolBolas said you need an interator to erase
. The full code looks like this:
int main(){
boost::property_tree::ptree pt;
read_xml("ptree_test.gexf", pt, boost::property_tree::xml_parser::trim_whitespace);
int id1, id2;
id1 = 0;
id2 = 1;
for(auto &e : pt.get_child("gexf.graph.edges")) {
int s, t;
s = e.second.get<int>("<xmlattr>.source");
t = e.second.get<int>("<xmlattr>.target");
// Check if this is the correct edge
// Two checks because it can be reversed
if((id1 == s && id2 == t) || (id1 == t && id2 == s)){
auto &children = e.second.get_child("<xmlattr>");
for(auto attrIt = children.begin(); attrIt != children.end(); ++attrIt){
if(attrIt->first == "end" || attrIt->first == "start")
attrIt = children.erase(attrIt);
}
break; // maybe shouldn't be here to keep looking?
}
}
write_xml("ptree_test_copy.gexf", pt, std::locale(), bpt::xml_writer_settings<std::string>{'\t', 1});
}
这篇关于提升属性树:从一个节点中删除属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!