2
Vote

yEd files deserialization

description

Hi,     First of all I'd like to say that QuickGraph is a impressive piece of work. Congratuations!   I'm looking for a way to read graphml files generated by yEd, a free graph editor. <cite>www.yworks.com/products/yed/</cite>   I can't easily figure out how to customize the Deserializer to read such Nodes, I get a not very meaningful error when trying to deserialize a graph (see xml below) with this code         var g = new AdjacencyGraph<string, Edge<string>>(); using (var xreader = XmlReader.Create("z:/test.graphml")) { g.DeserializeFromGraphML(xreader, id => id, (source, target, id) => new Edge<string>(source, target) ); }             <?xml version="1.0" encoding="UTF-8" standalone="no"?> <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.0/ygraphml.xsd"> <!--Created by yFiles for Java 2.7--> <key for="graphml" id="d0" yfiles.type="resources"/> <key attr.name="url" attr.type="string" for="node" id="d1"/> <key attr.name="description" attr.type="string" for="node" id="d2"/> <key for="node" id="d3" yfiles.type="nodegraphics"/> <key attr.name="url" attr.type="string" for="edge" id="d4"/> <key attr.name="description" attr.type="string" for="edge" id="d5"/> <key for="edge" id="d6" yfiles.type="edgegraphics"/> <graph edgedefault="directed" id="G"> <node id="n0"> <data key="d2"/> <data key="d3"> <y:ShapeNode> <y:Geometry height="30.0" width="30.0" x="365.0" y="11.0"/> <y:Fill color="#FFCC00" transparent="false"/> <y:BorderStyle color="#000000" type="line" width="1.0"/> <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="19.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="29.0" x="0.5" y="5.5">TICK</y:NodeLabel> <y:Shape type="ellipse"/> </y:ShapeNode> </data> </node> <node id="n1"> <data key="d2"/> <data key="d3"> <y:ShapeNode> <y:Geometry height="30.0" width="30.0" x="293.0" y="179.0"/> <y:Fill color="#FFCC00" transparent="false"/> <y:BorderStyle color="#000000" type="line" width="1.0"/> <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="19.0" modelName="internal" modelPosition="c" textColor="#000000" visible="true" width="30.0" x="0.0" y="5.5">SMA</y:NodeLabel> <y:Shape type="ellipse"/> </y:ShapeNode> </data> </node> <node id="n2"> <data key="d2"/> <data key="d3"> <y:ShapeNode> <y:Geometry height="30.0" width="30.0" x="652.0" y="244.0"/> <y:Fill color="#FFCC00" transparent="false"/> <y:BorderStyle color="#000000" type="line" width="1.0"/> <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="13" fontStyle="bold" hasBackgroundColor="false" hasLineColor="false" height="21.0" modelName="internal" modelPosition="t" textColor="#000000" visible="true" width="45.0" x="-7.5" y="4.0">SMA2</y:NodeLabel> <y:Shape type="rectangle"/> </y:ShapeNode> </data> </node> <edge id="e0" source="n0" target="n2"> <data key="d5"/> <data key="d6"> <y:PolyLineEdge> <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> <y:LineStyle color="#000000" type="line" width="1.0"/> <y:Arrows source="none" target="standard"/> <y:BendStyle smoothed="false"/> </y:PolyLineEdge> </data> </edge> <edge id="e1" source="n0" target="n1"> <data key="d5"/> <data key="d6"> <y:PolyLineEdge> <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> <y:LineStyle color="#000000" type="line" width="1.0"/> <y:Arrows source="none" target="standard"/> <y:BendStyle smoothed="false"/> </y:PolyLineEdge> </data> </edge> </graph> <data key="d0"> <y:Resources/> </data> </graphml>         What would be the minimum steps to read succesfully the graph, without data attached, and possibly with the data nodes as well?   Thanks for your help!   Alexandre

comments

rebcabin wrote Feb 1, 2011 at 3:40 PM

Hi, Alexandre -- I am not sure what your error is, but I solved some Namespace difficulties when reading such files with Linq-to-XML. Here is sample code that works over yEd graphml files

var graph = new AdjacencyGraph<string, Edge<string>>(true);

var file = @". . . your file path here . . .";
var theDoc = XDocument.Load(file);

(from node in theDoc.Descendants()
where node.Name.LocalName == "node"
select graph.AddVertex(node.Attribute("id").Value)).Run();

var edges = (from edge in theDoc.Descendants()
         where edge.Name.LocalName == "edge"
         select new Edge<string>(
           edge.Attribute("source").Value, 
           edge.Attribute("target").Value));
edges.Select(graph.AddEdge).Run();
var edgeCost = new Dictionary<Edge<string>, double>();
graph.Edges.Do(e => edgeCost.Add(e, 1)).Run();

var dijkstra = new DijkstraShortestPathAlgorithm<string, Edge<string>>(
graph, 
AlgorithmExtensions.GetIndexer<Edge<string>, double>(
    edgeCost));
var predObsvr = new QuickGraph.Algorithms.Observers
.VertexPredecessorRecorderObserver<string, Edge<string>>();
predObsvr.Attach(dijkstra);

var distObsvr = new VertexDistanceRecorderObserver<string, Edge<string>>(
AlgorithmExtensions.GetIndexer<Edge<string>, double>(edgeCost));
distObsvr.Attach(dijkstra);