I am using boost 1.53.0, I have implemented a small demo using boost for subgraph.
I need to export the subgraph information in the graphml file, while exporting it will create all the nodes in the parent graph but not able to hold the information about it's subraphs.
so please help me if there is any way to hold information about subgraph?.
My implementation is exporting as follows:
enter code here
<?xml version="1.0" encoding="UTF-8"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
<graph id="G" edgedefault="undirected" parse.nodeids="free"
parse.edgeids="canonical" parse.order="nodesfirst">
<node id="n0">
</node>
<node id="n1">
</node>
<node id="n2">
</node>
<node id="n3">
</node>
<node id="n4">
</node>
<node id="n5">
</node>
<edge id="e0" source="n0" target="n1">
</edge>
<edge id="e1" source="n1" target="n2">
</edge>
<edge id="e2" source="n1" target="n3">
</edge>
<edge id="e3" source="n4" target="n1">
</edge>
<edge id="e4" source="n4" target="n5">
</edge>
<edge id="e5" source="n5" target="n3">
</edge>
<edge id="e6" source="n2" target="n5">
</edge>
</graph>
</graphml>
Actully the nodes n0,n1,n2 are members of subgraph G1 and n4,n5 are members of subgrph G2.
G0 is main parent graph.
Following is the way to deal with above problem. This problem is solved by combining the use of dynamic properties from boost and also using bundled properties from boost.
this code works for boost 1_53_0.
Reference property map is used for storing the properties of boost subgraph.
#include <QtCore/QCoreApplication>
#include <boost/config.hpp>
#include <iostream>
#include <algorithm>
#include <boost/graph/adjacency_list.hpp>
#include <boost/property_map/property_map.hpp>
#include <string>
#include <boost/graph/subgraph.hpp>
#include <QMap>
using namespace std;
using namespace boost;
enum graph_IDproperty_t
{
graph_IDproperty
};
namespace boost
{
BOOST_INSTALL_PROPERTY(graph,IDproperty);
}
struct GraphProperties {
std::string strName;
std::string id;
};
typedef boost::subgraph<boost::adjacency_list< boost::listS,
boost::vecS,
boost::bidirectionalS,
boost::property<boost::vertex_index_t, int , property<boost::vertex_color_t, boost::default_color_type > > ,
boost::property<boost::edge_index_t,int, property<boost::edge_color_t , default_color_type> > ,
boost::property<graph_IDproperty_t,GraphProperties > > >
Graph;
Graph gMainGraph;
typedef QMap<Graph*,GraphProperties*> mapGraphToProperty;
mapGraphToProperty getMap(Graph& graph);
void graphMapRecur(mapGraphToProperty& map, Graph& graph);
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Graph& subG = gMainGraph.create_subgraph();
Graph& subG1 = gMainGraph.create_subgraph();
boost::ref_property_map<Graph*, GraphProperties>
graph_propt1(boost::get_property(subG1,graph_IDproperty));
graph_propt1[&subG1].id = "SubG1";
cout<<graph_propt1[&subG1].id<<endl;
boost::ref_property_map<Graph*, GraphProperties>
graph_propt(boost::get_property(subG,graph_IDproperty));
graph_propt[&subG].id = "SubG";
cout<<graph_propt[&subG].id<<endl;
boost::ref_property_map<Graph*, GraphProperties>
graph_proptMain(boost::get_property(gMainGraph,graph_IDproperty));
graph_proptMain[&gMainGraph].id = "gMain";
cout<<graph_proptMain[&gMainGraph].id<<endl;
mapGraphToProperty map = getMap(gMainGraph);
boost::ref_property_map<Graph*, GraphProperties>
graph_proptMain1(*(map.value(&gMainGraph)));
boost::ref_property_map<Graph*, GraphProperties>
graph_proptsubG(*(map.value(&subG)));
boost::ref_property_map<Graph*, GraphProperties>
graph_proptsubG1(*(map.value(&subG1)));
cout<<"Main G Value : "<<graph_proptMain1[&gMainGraph].id<<endl;
cout<<"Sub G Value : "<<graph_proptsubG[&subG].id<<endl;
cout<<"Sub G1 Value : "<<graph_proptsubG1[&subG1].id<<endl;
cout<<"Map Value Main: "<<(map.value(&gMainGraph))<<endl;
cout<<"Map Value SubG: "<<(map.value(&subG))<<endl;
cout<<"Map Value SubG1b: "<<(map.value(&subG1))<<endl;
return a.exec();
}
mapGraphToProperty getMap(Graph &graph)
{
mapGraphToProperty map;
graphMapRecur(map,graph);
return map;
}
void graphMapRecur(mapGraphToProperty &map, Graph &graph)
{
Graph::children_iterator itrSubgraph, itrSubgraph_end;
for (boost::tie(itrSubgraph, itrSubgraph_end) = (graph).children(); itrSubgraph != itrSubgraph_end; ++itrSubgraph)
{
graphMapRecur(map,(*itrSubgraph));
}
GraphProperties* gp = &(get_property(graph,graph_IDproperty));
map.insert(&graph,gp);
cout<<"Recurrr"<<endl;
}
Related
I'm currently trying to use RapidXML to write a file out, this is the code I've got for it
xml_document<> doc;
xml_node<>* decl = doc.allocate_node(node_declaration);
decl->append_attribute(doc.allocate_attribute("version", "1.0"));
decl->append_attribute(doc.allocate_attribute("encoding", "utf-8"));
doc.append_node(decl);
xml_node<> *root = doc.allocate_node(node_element, "config");
for(int i = 0; i < params.size(); i++) {
bool LineEdit = false;
std::pair<QLabel*, QLineEdit*> LabelAndLine;
LabelAndLine.first = ui->centralwidget->findChild<QLabel*>(params.at(i).first);
if (LabelAndLine.first == nullptr) {
LineEdit = true;
LabelAndLine.second = ui->centralwidget->findChild<QLineEdit*>(params.at(i).first);
}
QString nodename = params.at(i).second;
qInfo() << "Setting: "+nodename+" from "+params.at(i).first;
xml_node<> *param = doc.allocate_node(node_element, QStringToConstCharPoint(nodename));
xml_attribute<char> *value;
if (LineEdit) {
value = doc.allocate_attribute("value", QStringToConstCharPoint(LabelAndLine.second->text()));
}
else {
value = doc.allocate_attribute("value", QStringToConstCharPoint(LabelAndLine.first->text()));
}
param->append_attribute(value);
root->append_node(param);
}
doc.append_node(root);
std::string xmlName = std::to_string(time(NULL))+".xml";
std::ofstream fileStored(xmlName);
fileStored << doc;
fileStored.close();
doc.clear();
It reads a value from Qt (either a QLabel or a QLineEdit) then compares it to a vector of pairs (const QString, const QString) defined here:
std::vector<std::pair<const QString,const QString>> params = {{"PopulationInput","population"},
{"XInput","AreaX"},
{"YInput","AreaY"},
{"AlreadyInfectedInput","AlreadyInfected"},
{"InfectionProbabilityIndicator","infectProbability"},
{"RadOfInfectionInput","infectionRadius"},
{"CPUThreadsDisplay","threads"},
};
but when I look at the output file it just shows this:
<?xml version="1.0" encoding="utf-8"?>
<config>
<ding="utf-8"?>
<config>
<ding="utf-8"?>
<co value='ding="utf-8"'/>
<ding="utf-8" value='ding="utf-8"'/>
<ding="utf-8" value='ding="utf-8"'/>
<ding="utf-8"?>
<config>
<ding="utf-8"?>
<co value='ding="utf-8"'/>
<ding="utf-8"?>
<config>
<ding="utf-8"?>
<co value='ding="utf-8"'/>
<ding="utf-8"?>
<config>
<ding="utf-8"?>
<co value='ding="utf-8"'/>
<ding="utf-8"?>
<config>
<ding="utf-8"?>
<co value='ding="utf-8"'/>
</config>
The QStringToConstCharPoint function is defined as this:
const char* QStringToConstCharPoint(QString input) {
QByteArray ba = input.toLocal8Bit();
const char *result = ba.data();
return result;
}
Why is my output looking like that? Have I done something wrong?
Turns out the QStringToConstCharPoint function was the issue, it was messing something up with RapidXML and I don't know why, but I found a better way to do it.
my c++ code as below, and I want to use Doxygen produce xml file.
// c++ code
struct TestStru
{
struct{
int a;
} m_stru;
union{
int b;
char c;
} m_union;
int d;
};
The real output xml as follows, I omitted some information not important. My question is how to distinguish members in anonymous struct or union like 'a' from xml, or how could I configure Doxygen to achieve this.
<memberdef kind="variable" id="struct_test_stru_1a898ff9a1bccfc215accd3da2db864509" prot="public" static="no" mutable="no">
<type>int</type>
<definition>int TestStru::a</definition>
<argsstring></argsstring>
<name>a</name>
</memberdef>
<memberdef kind="variable" id="struct_test_stru_1aeca04a3d70feb1cef125df66625487ef" prot="public" static="no" mutable="no">
<type>struct TestStru::#0</type>
<definition>struct TestStru::#0 TestStru::m_stru</definition>
<argsstring></argsstring>
<name>m_stru</name>
</memberdef>
<memberdef kind="variable" id="struct_test_stru_1a2831fb7fc8f16abb913fe9a3c1fae19a" prot="public" static="no" mutable="no">
<type>int</type>
<definition>int TestStru::b</definition>
<argsstring></argsstring>
<name>b</name>
</memberdef>
<memberdef kind="variable" id="struct_test_stru_1aaa51d26f2195dcfdb0ce8f500275221b" prot="public" static="no" mutable="no">
<type>char</type>
<definition>char TestStru::c</definition>
<argsstring></argsstring>
<name>c</name>
</memberdef>
<memberdef kind="variable" id="struct_test_stru_1a547ce77ff0347d5a14ac43e078964022" prot="public" static="no" mutable="no">
<type>union TestStru::#1</type>
<definition>union TestStru::#1 TestStru::m_union</definition>
</memberdef>
<memberdef kind="variable" id="struct_test_stru_1a5437512aa23a668c8e10865521c35f7c" prot="public" static="no" mutable="no">
<type>int</type>
<definition>int TestStru::d</definition>
<argsstring></argsstring>
<name>d</name>
</memberdef>
I have just downloaded the pugixml library and I am trying to adapt it to my needs. It is mostly oriented for DOM style which I am not using. The data I store looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<profile>
<points>
<point>
<index>0</index>
<x>0</x>
<y>50</y>
</point>
<point>
<index>1</index>
<x>2</x>
<y>49.9583</y>
</point>
<point>
<index>2</index>
<x>12</x>
<y>50.3083</y>
</point>
</points>
</profile>
Pugixml guide says:
It is common to store data as text contents of some node - i.e.
This is a node. In this case,
node does not have a value, but instead has a child of
type node_pcdata with value "This is a node". pugixml provides
child_value() and text() helper functions to parse such data.
But I am having problem with using those methods, I am not getting the node values out.
#include "pugixml.hpp"
#include <string.h>
#include <iostream>
int main()
{
pugi::xml_document doc;
if (!doc.load_file("/home/lukasz/Programy/eclipse_linux_projects/xmlTest/Debug/pidtest.xml"))
return -1;
pugi::xml_node points = doc.child("profile").child("points");
for (pugi::xml_node point = points.first_child(); point; point = points.next_sibling())
{
// ?
}
return 0;
}
How to read out the index, x and y values inside of the for? I Would aprichiate all help.
There are several ways, documented in the quickstart page:
http://pugixml.org/docs/samples/traverse_iter.cpp
http://pugixml.org/docs/samples/traverse_rangefor.cpp
there is a tree visitor for the power jobs http://pugixml.org/docs/samples/traverse_walker.cpp
May I suggest Xpath?
#include <pugixml.hpp>
#include <iostream>
int main()
{
pugi::xml_document doc;
if (doc.load_file("input.txt")) {
for (auto point : doc.select_nodes("//profile/points/point")) {
point.node().print(std::cout, "", pugi::format_raw);
std::cout << "\n";
}
}
}
Prints
<point><index>0</index><x>0</x><y>50</y></point>
<point><index>1</index><x>2</x><y>49.9583</y></point>
<point><index>2</index><x>12</x><y>50.3083</y></point>
I have a piece of code that iterates over a boost property tree (XML).
I need a ptree of the current node, not the children of the node.
UPDATE
xml tree
<node id="A.html">
<subnode> child A1 </subnode>
<subnode> child A2 </subnode>
</node>
<node id="B.html">
<subnode> child B1 </subnode>
<subnode> child B2 </subnode>
</node>
itteration code
void parse_tree(ptree& pt, std::string key)
{
string nkey;
if (!key.empty())
nkey = key + ".";
ptree::const_iterator end = pt.end();
for(ptree::iterator it = pt.begin(); it != end; ++it){
//if the node's id is a .html filname, save the node to file
string id = it->second.get("<xmlattr>.id","");
if(id.find("B.html") != std::string::npos){ //Let's just test for "B.html"
write_xml("test.html", pt); //saves entire tree
write_xml("test.html", it->second); //saves only children of the node
}
parse_tree(it->second, nkey + it->first); //recursion
}
}
Results using write_xml("test.html", pt)
(We get the entire tree, we only want the node)
<node id="A.html">
<subnode> child A1 </subnode>
<subnode> child A2 </subnode>
</node>
<node id="B.html">
<subnode> child B1 </subnode>
<subnode> child B2 </subnode>
</node>
Results using write_xml("test.html", it->second)
(We have no parent node.. only child nodes)
<subnode> child B1 </subnode>
<subnode> child B2 </subnode>
Desired result
(We want the node, and it's children,.. like so)
<node id="B.html">
<subnode> child B1 </subnode>
<subnode> child B2 </subnode>
</node>
UPDATE 2
Rewritten in response to the comment/updated question.
There are two ways.
You can use the undocumented function write_xml_element to write the single element (using the key as element name):
// write the single element: (undocumented API)
boost::property_tree::xml_parser::write_xml_element(
std::cout, it->first, it->second,
0, settings
);
or you can create a new ptree object with the single child
ptree tmp;
tmp.add_child(it->first, it->second);
write_xml(std::cout, tmp, settings);
Live On Coliru
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <fstream>
#include <iostream>
using namespace boost::property_tree;
void parse_tree(ptree& pt, std::string key)
{
std::string nkey;
auto settings = xml_parser::xml_writer_make_settings<std::string>('\t', 1);
if (!key.empty()) {
nkey = key + ".";
}
ptree::const_iterator end = pt.end();
for(ptree::iterator it = pt.begin(); it != end; ++it)
{
//if the node's id an .html filname, save the node to file
std::string id = it->second.get("<xmlattr>.id","");
if (id.find(key) != std::string::npos) {
// write the single element: (undocumented API)
boost::property_tree::xml_parser::write_xml_element(
std::cout, it->first, it->second,
0, settings
);
// or: create a new pt with the single child
std::cout << "\n==========================\n\n";
ptree tmp;
tmp.add_child(it->first, it->second);
write_xml(std::cout, tmp, settings);
}
parse_tree(it->second, nkey + it->first); //recursion
}
}
int main() {
ptree pt;
read_xml("input.txt", pt);
parse_tree(pt, "B");
}
Output:
<node id="B.html">
<subnode> child B1 </subnode>
<subnode> child B2 </subnode>
</node>
==========================
<?xml version="1.0" encoding="utf-8"?>
<node id="B.html">
<subnode> child B1 </subnode>
<subnode> child B2 </subnode>
</node>
This question already has answers here:
boost::property_tree XML pretty printing
(4 answers)
Closed 8 years ago.
I'm using Boost Property Trees to export my class-instants as XML nodes.
It works but it just puts everything in 1 line. I would like it to have indents, like:
<?xml version="1.0" encoding="utf-8"?>
<root>
<sensorconfigurations>
<configuration>
<name>SensorConfiguration1</name>
<sensorid>1</sensorid>
<signalindex>1</signalindex>
<mappingscheme>mappingscheme1</mappingscheme>
<soundpack>test1.wav</soundpack>
</configuration>
<configuration>
<name>SensorConfiguration2</name>
<sensorid>2</sensorid>
<signalindex>2</signalindex>
<mappingscheme>mappingscheme1</mappingscheme>
<soundpack>test2.wav</soundpack>
</configuration>
<configuration>
<name>SensorConfiguration3</name>
<sensorid>3</sensorid>
<signalindex>3</signalindex>
<mappingscheme>mappingscheme2</mappingscheme>
<soundpack>test3.wav</soundpack>
</configuration>
</sensorconfigurations>
</root>
Is this possible somehow? Am I missing a parameter in the write_xml method?
Here's my code:
void SensorConfigurationBank::save()
{
using boost::property_tree::ptree;
ptree pt;
for(map<string, SensorConfiguration>:: iterator it = sensorConfigurations_.begin(); it != sensorConfigurations_.end(); ++it)
{
ptree myTree;
myTree.put("name", it->second.getName());
myTree.put("sensorid", it->second.getSensorID());
myTree.put("signalindex", it->second.getsignalIndex());
MappingScheme myScheme = it->second.getMScheme();
myTree.put("mappingscheme", myScheme.getId());
SoundPack mySound = it->second.getSound();
myTree.put("soundpack", mySound.filepath_);
pt.add_child("root.sensorconfigurations.configuration", myTree);
}
write_xml("SensorConfigurationBank2.xml", pt);
}
These days, xml_writer_settings apparently takes a string type as template argument, so:
boost::property_tree::xml_writer_settings<std::string> settings('\t', 1);
write_xml(std::cout, pt, settings);
will do the trick. Full sample:
Live On Coliru
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <map>
#include <iostream>
struct SoundPack {
std::string filepath_ = "soundpack.wav";
};
struct MappingScheme {
std::string getId() const { return "Id"; }
};
struct SensorConfiguration {
std::string getName() const { return "Name"; }
std::string getSensorID() const { return "SensorID"; }
std::string getsignalIndex() const { return "signalIndex"; }
SoundPack getSound() const { return {}; }
MappingScheme getMScheme() const { return {}; }
};
void save(std::map<std::string, SensorConfiguration> sensorConfigurations_)
{
using boost::property_tree::ptree;
ptree pt;
for(std::map<std::string, SensorConfiguration>:: iterator it = sensorConfigurations_.begin(); it != sensorConfigurations_.end(); ++it)
{
ptree myTree;
MappingScheme myScheme = it->second.getMScheme();
SoundPack mySound = it->second.getSound();
myTree.put("name", it->second.getName());
myTree.put("sensorid", it->second.getSensorID());
myTree.put("signalindex", it->second.getsignalIndex());
myTree.put("mappingscheme", myScheme.getId());
myTree.put("soundpack", mySound.filepath_);
pt.add_child("root.sensorconfigurations.configuration", myTree);
}
boost::property_tree::xml_writer_settings<std::string> settings('\t', 1);
write_xml(std::cout, pt, settings);
}
int main() {
save({
{ "first", SensorConfiguration {} },
{ "second", SensorConfiguration {} },
{ "third", SensorConfiguration {} },
{ "fourth", SensorConfiguration {} }
});
}
Output:
<?xml version="1.0" encoding="utf-8"?>
<root>
<sensorconfigurations>
<configuration>
<name>Name</name>
<sensorid>SensorID</sensorid>
<signalindex>signalIndex</signalindex>
<mappingscheme>Id</mappingscheme>
<soundpack>soundpack.wav</soundpack>
</configuration>
<configuration>
<name>Name</name>
<sensorid>SensorID</sensorid>
<signalindex>signalIndex</signalindex>
<mappingscheme>Id</mappingscheme>
<soundpack>soundpack.wav</soundpack>
</configuration>
<configuration>
<name>Name</name>
<sensorid>SensorID</sensorid>
<signalindex>signalIndex</signalindex>
<mappingscheme>Id</mappingscheme>
<soundpack>soundpack.wav</soundpack>
</configuration>
<configuration>
<name>Name</name>
<sensorid>SensorID</sensorid>
<signalindex>signalIndex</signalindex>
<mappingscheme>Id</mappingscheme>
<soundpack>soundpack.wav</soundpack>
</configuration>
</sensorconfigurations>
</root>