From 02fbda42720fc3f5cef04ab2d57db12ad3d2b523 Mon Sep 17 00:00:00 2001 From: Josef Cibulka Date: Fri, 26 Sep 2014 16:28:22 +0200 Subject: [PATCH] Added reading of graph properties from graphml. --- include/boost/graph/graphml.hpp | 4 ++-- src/graphml.cpp | 38 +++++++++++++++++++++++++++++---- test/graphml_test.cpp | 12 ++++++++++- test/graphml_test.xml | 3 +++ 4 files changed, 50 insertions(+), 7 deletions(-) diff --git a/include/boost/graph/graphml.hpp b/include/boost/graph/graphml.hpp index be73def3..a7faa647 100644 --- a/include/boost/graph/graphml.hpp +++ b/include/boost/graph/graphml.hpp @@ -97,8 +97,8 @@ class mutate_graph_impl : public mutate_graph bool type_found = false; try { - mpl::for_each(put_property - (name, m_dp, m_g, value, value_type, m_type_names, type_found)); + mpl::for_each(put_property + (name, m_dp, &m_g, value, value_type, m_type_names, type_found)); } catch (bad_lexical_cast) { diff --git a/src/graphml.cpp b/src/graphml.cpp index 76ef0a29..302d03a5 100644 --- a/src/graphml.cpp +++ b/src/graphml.cpp @@ -33,16 +33,29 @@ public: return boost::property_tree::ptree::path_type(str, '/'); } - static void get_graphs(const boost::property_tree::ptree& top, - size_t desired_idx /* or -1 for all */, + void get_graphs(const boost::property_tree::ptree& top, + size_t desired_idx /* or -1 for all */, bool is_root, std::vector& result) { using boost::property_tree::ptree; size_t current_idx = 0; + bool is_first = is_root; BOOST_FOREACH(const ptree::value_type& n, top) { if (n.first == "graph") { if (current_idx == desired_idx || desired_idx == (size_t)(-1)) { result.push_back(&n.second); - get_graphs(n.second, (size_t)(-1), result); + if(is_first) + { + is_first = false; + BOOST_FOREACH(const ptree::value_type& attr, n.second) { + if (attr.first != "data") + continue; + std::string key = attr.second.get(path("/key")); + std::string value = attr.second.get_value(""); + handle_graph_property(key, value); + } + } + + get_graphs(n.second, (size_t)(-1), false, result); if (desired_idx != (size_t)(-1)) break; } ++current_idx; @@ -81,7 +94,8 @@ public: } // Search for graphs std::vector graphs; - get_graphs(gml, desired_idx, graphs); + handle_graph(); + get_graphs(gml, desired_idx, true, graphs); BOOST_FOREACH(const ptree* gr, graphs) { // Search for nodes BOOST_FOREACH(const ptree::value_type& node, *gr) { @@ -193,6 +207,22 @@ private: } } + void + handle_graph() + { + std::map::iterator iter; + for (iter = m_key_default.begin(); iter != m_key_default.end(); ++iter) + { + if (m_keys[iter->first] == graph_key) + handle_graph_property(iter->first, iter->second); + } + } + + void handle_graph_property(const std::string& key_id, const std::string& value) + { + m_g.set_graph_property(m_key_name[key_id], value, m_key_type[key_id]); + } + void handle_node_property(const std::string& key_id, const std::string& descriptor, const std::string& value) { m_g.set_vertex_property(m_key_name[key_id], m_vertex[descriptor], value, m_key_type[key_id]); diff --git a/test/graphml_test.cpp b/test/graphml_test.cpp index 972768e8..987fd9cf 100644 --- a/test/graphml_test.cpp +++ b/test/graphml_test.cpp @@ -39,12 +39,16 @@ int main(int argc, char** argv) typedef adjacency_list >, - property > graph_t; + property, + property > graph_t; graph_t g; dynamic_properties dp; dp.property("foo",get(vertex_color_t(),g)); dp.property("weight",get(edge_weight_t(),g)); dp.property("name",get(vertex_name_t(),g)); + boost::ref_property_map + gname(get_property(g, graph_name)); + dp.property("description",gname); ifstream ifile(argv[1]); read_graphml(ifile, g, dp); @@ -56,6 +60,8 @@ int main(int argc, char** argv) assert(get(vertex_color_t(), g, vertex(3,g)) == 42); assert(get(edge_weight_t(), g, edge(vertex(0,g),vertex(1,g),g).first) == 0.0); assert(get(edge_weight_t(), g, edge(vertex(1,g),vertex(2,g),g).first) == 0.8); + assert(get("description", dp, &g) == "Root graph."); + ofstream ofile("graphml_test_out.xml"); write_graphml(ofile, g, dp); @@ -66,12 +72,16 @@ int main(int argc, char** argv) dp2.property("foo",get(vertex_color_t(),g2)); dp2.property("weight",get(edge_weight_t(),g2)); dp2.property("name",get(vertex_name_t(),g2)); + boost::ref_property_map + gname2(get_property(g2, graph_name)); + dp2.property("description",gname2); ifile.open("graphml_test_out.xml"); read_graphml(ifile, g2, dp2); ifile.close(); assert(num_vertices(g) == num_vertices(g2)); assert(num_edges(g) == num_edges(g2)); + assert(get("description", dp, &g) == get("description", dp2, &g2)); graph_traits::vertex_iterator v, v_end; for (boost::tie(v,v_end) = vertices(g); v != v_end; ++v) diff --git a/test/graphml_test.xml b/test/graphml_test.xml index f805fa23..467d29bb 100644 --- a/test/graphml_test.xml +++ b/test/graphml_test.xml @@ -18,8 +18,10 @@ hello + + Root graph. @@ -56,6 +58,7 @@ 0.1 + Nested graph.