Commit 15f1ba1b authored by Tiago Peixoto's avatar Tiago Peixoto

graphml: load vertex and edge ids as string properties, if not canonical

parent cf3440f4
......@@ -244,14 +244,14 @@ const char* mutate_graph_impl<MutableGraph>::m_type_names[] =
"python_object"};
void
read_graphml(std::istream& in, mutate_graph& g);
read_graphml(std::istream& in, mutate_graph& g, bool store_ids);
template<typename MutableGraph>
void
read_graphml(std::istream& in, MutableGraph& g, dynamic_properties& dp)
read_graphml(std::istream& in, MutableGraph& g, dynamic_properties& dp, bool store_ids)
{
mutate_graph_impl<MutableGraph> mg(g,dp);
read_graphml(in, mg);
read_graphml(in, mg, store_ids);
}
template <typename Types>
......@@ -339,9 +339,24 @@ write_graphml(std::ostream& out, const Graph& g, VertexIndexMap vertex_index,
out << " <!-- property keys -->\n";
bool has_vertex_ids = false;
bool has_edge_ids = false;
// Output keys
for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end(); ++i)
{
if (i->first == "_graphml_vertex_id")
{
has_vertex_ids = true;
continue;
}
if (i->first == "_graphml_edge_id")
{
has_edge_ids = true;
continue;
}
std::string key_id = "key" + lexical_cast<std::string>(key_count++);
if (i->second->key() == typeid(graph_property_tag))
graph_key_ids[i->first] = key_id;
......@@ -364,11 +379,15 @@ write_graphml(std::ostream& out, const Graph& g, VertexIndexMap vertex_index,
<< " />\n";
}
bool canonical_vertices = ordered_vertices && !has_vertex_ids;
bool canonical_edges = !has_edge_ids;
out << "\n <graph id=\"G\" edgedefault=\""
<< (graph_is_directed ? "directed" : "undirected") << "\""
<< " parse.nodeids=\"" << (ordered_vertices ? "canonical" : "free")
<< " parse.nodeids=\"" << (canonical_vertices ? "canonical" : "free")
<< "\""
<< " parse.edgeids=\"canonical\" parse.order=\"nodesfirst\">\n\n";
<< " parse.edgeids=\"" << (canonical_edges ? "canonical" : "free")
<< "\" parse.order=\"nodesfirst\">\n\n";
out << " <!-- graph properties -->\n";
// Output graph data
......@@ -392,11 +411,20 @@ write_graphml(std::ostream& out, const Graph& g, VertexIndexMap vertex_index,
vertex_iterator v, v_end;
for (tie(v, v_end) = vertices(g); v != v_end; ++v)
{
out << " <node id=\"n" << get(vertex_index, *v) << "\">\n";
out << " <node id=\"";
if (has_vertex_ids)
out << protect_xml_string(get("_graphml_vertex_id", dp, *v));
else
out << "n" << get(vertex_index, *v);
out << "\">\n";
// Output data
for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end();
++i)
{
if (i->first == "_graphml_vertex_id")
continue;
if (i->second->key() == typeid(vertex_descriptor))
{
std::string val = protect_xml_string
......@@ -417,14 +445,34 @@ write_graphml(std::ostream& out, const Graph& g, VertexIndexMap vertex_index,
typename graph_traits<Graph>::edges_size_type edge_count = 0;
for (tie(e, e_end) = edges(g); e != e_end; ++e)
{
out << " <edge id=\"e" << edge_count++ << "\" source=\"n"
<< get(vertex_index, source(*e, g)) << "\" target=\"n"
<< get(vertex_index, target(*e, g)) << "\">\n";
out << " <edge id=\"";
if (has_edge_ids)
out << protect_xml_string(get("_graphml_edge_id", dp, *e));
else
out << "e" << edge_count;
edge_count++;
out << "\" source=\"";
if (has_vertex_ids)
out << protect_xml_string(get("_graphml_vertex_id", dp,
source(*e, g)));
else
out << "n" << get(vertex_index, source(*e, g));
out << "\" target=\"";
if (has_vertex_ids)
out << protect_xml_string(get("_graphml_vertex_id", dp,
target(*e, g)));
else
out << "n" << get(vertex_index, target(*e, g));
out<< "\">\n";
// Output data
for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end();
++i)
{
if (i->first == "_graphml_edge_id")
continue;
if (i->second->key() == typeid(edge_descriptor))
{
std::string val = protect_xml_string
......
......@@ -367,10 +367,7 @@ void build_stream
python::tuple GraphInterface::ReadFromFile(string file, python::object pfile,
string format)
{
bool graphviz = false;
if (format == "dot")
graphviz = true;
else if (format != "xml")
if (format != "dot" && format != "xml" && format != "auto")
throw ValueException("error reading from file '" + file +
"': requested invalid format '" + format + "'");
try
......@@ -390,10 +387,10 @@ python::tuple GraphInterface::ReadFromFile(string file, python::object pfile,
_directed = true;
try
{
if (graphviz)
if (format == "dot")
read_graphviz(stream, wg, dp, "vertex_name");
else
read_graphml(stream, wg, dp);
read_graphml(stream, wg, dp, true);
}
catch (const undirected_graph_error&)
{
......@@ -407,10 +404,10 @@ python::tuple GraphInterface::ReadFromFile(string file, python::object pfile,
build_stream(stream, file, pfile, file_stream);
FakeUndirGraph<GraphEdgeIndexWrap<multigraph_t,edge_index_map_t> >
ug(wg);
if (graphviz)
if (format == "dot")
read_graphviz(stream, ug, dp, "vertex_name");
else
read_graphml(stream, ug, dp);
read_graphml(stream, ug, dp, true);
}
_state->_nedges = num_edges(_state->_mg);
_state->_max_edge_index = (_state->_nedges > 0) ?
......
......@@ -33,8 +33,8 @@ std::string protect_xml_string(const std::string& os)
class graphml_reader
{
public:
graphml_reader(mutate_graph& g)
: m_g(g), m_canonical_vertices(false) { }
graphml_reader(mutate_graph& g, bool store_ids)
: m_g(g), m_canonical_vertices(false), m_store_ids(store_ids) { }
void run(std::istream& in)
{
......@@ -111,7 +111,7 @@ private:
}
self->m_active_descriptor = self->m_edge.size();
self->handle_edge(source, target);
self->handle_edge(id, source, target);
}
else if (name == "node")
{
......@@ -202,6 +202,10 @@ private:
{
self->m_canonical_vertices = (value == "canonical");
}
else if (name == "parse.edgeids")
{
self->m_canonical_edges = (value == "canonical");
}
}
self->m_active_descriptor = "";
}
......@@ -282,6 +286,10 @@ private:
if (m_keys[iter->first] == node_key)
handle_property(iter->first, v, iter->second);
}
if (m_store_ids && !m_canonical_vertices)
m_g.set_vertex_property("_graphml_vertex_id",
get_vertex_descriptor(v),
v, "string");
}
}
......@@ -301,7 +309,8 @@ private:
}
void
handle_edge(const std::string& u, const std::string& v)
handle_edge(const std::string& id, const std::string& u,
const std::string& v)
{
handle_vertex(u);
handle_vertex(v);
......@@ -325,6 +334,11 @@ private:
if (m_keys[iter->first] == edge_key)
handle_property(iter->first, e, iter->second);
}
if (m_store_ids && !m_canonical_edges)
m_g.set_edge_property("_graphml_edge_id", get_edge_descriptor(e),
id, "string");
}
void handle_property(const std::string& key_id,
......@@ -381,15 +395,16 @@ private:
std::string m_character_data;
bool m_canonical_vertices;
bool m_canonical_edges;
bool m_store_ids;
XML_Parser m_parser;
};
namespace boost
{
void
read_graphml(std::istream& in, mutate_graph& g)
read_graphml(std::istream& in, mutate_graph& g, bool store_ids)
{
graphml_reader reader(g);
graphml_reader reader(g, store_ids);
reader.run(in);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment