diff --git a/src/LightGraphs.jl b/src/LightGraphs.jl index 994b9906c..af16fe62f 100644 --- a/src/LightGraphs.jl +++ b/src/LightGraphs.jl @@ -69,7 +69,7 @@ module LightGraphs a_star, # persistence - readgraph, + readgraph, read_graphml, # randgraphs erdos_renyi, watts_strogatz diff --git a/src/persistence.jl b/src/persistence.jl index 03484a8fa..82503cdad 100644 --- a/src/persistence.jl +++ b/src/persistence.jl @@ -62,3 +62,83 @@ function write( close(f) return res end + + + +_HAS_LIGHTXML = try + using LightXML + true + catch + false + end + +if _HAS_LIGHTXML + +#@doc """ +#Reads in a GraphML file as an array of Graphs or Digraphs +# +#Input: +# +# filename +# +#Returns: +# +# An array of (name, AbstractGraph) tuple +#""" -> +function read_graphml(filename::String) + xdoc = parse_file(filename) + xroot = root(xdoc) # an instance of XMLElement + name(xroot) == "graphml" || error("Not a GraphML file") + + # traverse all its child nodes and print element names + graphs = (String, AbstractGraph)[] + for c in child_nodes(xroot) # c is an instance of XMLNode + if is_elementnode(c) + e = XMLElement(c) # this makes an XMLElement instance + if name(e) == "graph" + nodes = Dict{String,Int}() + edges = (Int, Int)[] + graphname = has_attribute(e, "id") ? attribute(e, "id") : nothing + edgedefault = attribute(e, "edgedefault") + isdirected = edgedefault=="directed" ? true : + edgedefault=="undirected" ? false : error("Unknown value of edgedefault: $edgedefault") + else + error("Unknown node $(name(e))") + end + + nodeid = 1 + for f in child_elements(e) + if name(f) == "node" + nodes[attribute(f, "id")] = nodeid + nodeid += 1 + elseif name(f) == "edge" + n1 = attribute(f, "source") + n2 = attribute(f, "target") + push!(edges, (nodes[n1], nodes[n2])) + else + error("Unknown node $(name(f))") + end + end + #Put data in graph + g = (isdirected ? DiGraph : Graph)(length(nodes)) + for (n1, n2) in edges + add_edge!(g, n1, n2) + end + push!(graphs, (graphname, g)) + end + end + graphs +end + +else + +#@doc """ +#Reads in a GraphML file as an array of Graphs or Digraphs +# +#Requires the LightXML package to be insta. +#""" -> +function read_graphml(filename::String) + error("needs LightXML") +end + +end diff --git a/test/data/grafo1853.13.graphml b/test/data/grafo1853.13.graphml new file mode 100644 index 000000000..0d9edaa15 --- /dev/null +++ b/test/data/grafo1853.13.graphml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/persistence.jl b/test/persistence.jl index e12ce6099..bedf20425 100644 --- a/test/persistence.jl +++ b/test/persistence.jl @@ -7,3 +7,23 @@ @test length(sprint(write, p2)) == 51 rm(f) + +_HAVE_LIGHTXML = try + using LightXML + true + catch + false + end + +if _HAVE_LIGHTXML +#Try reading in a GraphML file from the Rome Graph collection +#http://www.graphdrawing.org/data/ +let Gs = read_graphml("data/grafo1853.13.graphml") + @test length(Gs) == 1 + @test Gs[1][1] == "G" #Name of graph + G = Gs[1][2] + @test nv(G) == 13 + @test ne(G) == 15 +end +end # _HAVE_LIGHTXML +