Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Initial GraphML parser

  • Loading branch information...
commit 4dd50f1795971c759066cdc56e664a53ee1bc9db 0 parents
Will Cannings authored
4 .gitignore
@@ -0,0 +1,4 @@
+*.gem
+.bundle
+Gemfile.lock
+pkg/*
4 Gemfile
@@ -0,0 +1,4 @@
+source "http://rubygems.org"
+
+# Specify your gem's dependencies in ruby-graphml.gemspec
+gemspec
1  Rakefile
@@ -0,0 +1 @@
+require "bundler/gem_tasks"
183 lib/ruby-graphml.rb
@@ -0,0 +1,183 @@
+require 'nokogiri'
+
+module GraphML
+ VERSION = "0.0.1"
+
+ class Key
+ attr_accessor :id, :for, :name, :type, :desc, :default
+ def initialize(attrs)
+ attrs.each do |key, val|
+ case key
+ when 'id'
+ @id = val
+ when 'for'
+ @for = val
+ when 'attr.name'
+ @name = val
+ when 'attr.type'
+ @type = val
+ end
+ end
+ @desc = ''
+ @default = ''
+ end
+
+ def append(key, val)
+ if key == 'desc'
+ @desc += val
+ elsif key == 'default'
+ @default += val
+ end
+ end
+ end
+
+ class Edge
+ def initialize(attrs, graph)
+ attrs.each do |key, val|
+ if key == 'source'
+ @source = val
+ elsif key == 'target'
+ @target = val
+ end
+ end
+ @graph = graph
+ source.out_edges << self
+ target.in_edges << self
+ end
+
+ def source
+ @graph.nodes[@source]
+ end
+
+ def target
+ @graph.nodes[@target]
+ end
+ end
+
+ class Node
+ attr_accessor :id, :data, :in_edges, :out_edges
+ def initialize(attrs, graph)
+ attrs.each do |key, val|
+ if key == 'id'
+ @id = val
+ end
+ end
+ @data = {}
+ @in_edges = []
+ @out_edges = []
+ @graph = graph
+ end
+
+ def key(name)
+ key_obj = @graph.key_names[name]
+ val = @data[key_obj.id]
+ return key_obj.default if val.nil?
+ val
+ end
+ end
+
+ class Graph
+ attr_accessor :keys, :key_names, :nodes, :edges
+
+ def initialize
+ @keys = {}
+ @key_names = {}
+ @nodes = {}
+ @edges = []
+ end
+ end
+
+ class Parser < Nokogiri::XML::SAX::Document
+ attr_reader :graph
+
+ def self.parse!(path)
+ parser = self.new
+ graph = parser.graph
+ parser = Nokogiri::XML::SAX::Parser.new(parser).parse(File.open(path, 'rb'))
+ graph
+ end
+
+ def initialize
+ @current_node = nil
+ @current_key = nil
+ @current_edge = nil
+ @state = nil
+ @sub_state = nil
+ @graph = Graph.new
+ end
+
+ def start_element(name, attrs=[])
+ case @state
+ # creating a new key, node or edge
+ when nil
+ case name
+ when 'key'
+ @current_key = Key.new(attrs)
+ @graph.keys[@current_key.id] = @current_key
+ @graph.key_names[@current_key.name] = @current_key
+ when 'node'
+ @current_node = Node.new(attrs, @graph)
+ @graph.nodes[@current_node.id] = @current_node
+ when 'edge'
+ @current_edge = Edge.new(attrs, @graph)
+ @graph.edges << @current_edge
+ else
+ return
+ end
+ @state = name
+ @sub_state = nil
+
+ # adding to a key
+ when 'key'
+ raise 'Missing key object' if @current_key.nil?
+ @sub_state = name
+
+ # adding a key value to a node
+ when 'node'
+ raise 'Missing node object' if @current_node.nil?
+ raise 'Unexpected attribute' if attrs[0][0] != 'key'
+ @sub_state = attrs[0][1]
+ end
+ end
+
+ def characters(string)
+ return if @sub_state.nil?
+ case @state
+ when 'key'
+ raise 'Missing key object' if @current_key.nil?
+ @current_key.append(@sub_state, string)
+ when 'node'
+ raise 'Missing node object' if @current_node.nil?
+ @current_node.data[@sub_state] ||= ''
+ @current_node.data[@sub_state] += string
+ end
+ end
+
+ def end_element(name)
+ case @state
+ when 'node'
+ if name == 'node'
+ @current_node = nil
+ @state = nil
+ else
+ @sub_state = nil
+ end
+ when 'edge'
+ if name == 'edge'
+ @current_edge = nil
+ @state = nil
+ else
+ @sub_state = nil
+ end
+ when 'key'
+ if name == 'key'
+ @current_key = nil
+ @state = nil
+ else
+ @sub_state = nil
+ end
+ end
+ end
+ end
+
+end
22 ruby-graphml.gemspec
@@ -0,0 +1,22 @@
+# -*- encoding: utf-8 -*-
+$:.push File.expand_path("../lib", __FILE__)
+require "ruby-graphml"
+
+Gem::Specification.new do |s|
+ s.name = "ruby-graphml"
+ s.version = GraphML::VERSION
+ s.authors = ["Will"]
+ s.email = ["me@willcannings.com"]
+ s.homepage = ""
+ s.summary = %q{Ruby GraphML Parser}
+ s.description = %q{Ruby GraphML Parser}
+
+ s.files = `git ls-files`.split("\n")
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
+ s.require_paths = ["lib"]
+
+ # specify any dependencies here; for example:
+ # s.add_development_dependency "rspec"
+ s.add_runtime_dependency "nokogiri"
+end
Please sign in to comment.
Something went wrong with that request. Please try again.