module Calais class Response attr_reader :rdf, :names, :relationships, :error def initialize(raw, error=nil) @error = error @names = [] @relationships = [] parse_raw(raw) return if @error parse_names parse_relationships end Name::TYPES.each_pair do |method_name, type| define_method method_name.to_sym do @names.map {|name| name if name.type == type }.compact end end private def parse_raw(raw) @libxml = XML::Parser.string(XML::Parser.string(raw).parse.root.child.content).parse @rdf = @libxml.to_s @error = @libxml.find("/Error/Exception").first.content rescue @error end def parse_names @names = @libxml.root.find("rdf:Description/rdf:type[contains(@rdf:resource, '/em/e/')]/..").map do |n| name = n.find_first("c:name").content type = n.find_first("rdf:type").properties.to_a.assoc("resource").last.split('/').last hash = n.properties.to_a.assoc("about").last.split("/").last locations = @libxml.root.find("rdf:Description/c:subject[contains(@rdf:resource, '#{hash}')]/..").map do |n2| start = n2.find_first("c:offset").content.to_i Range.new(start, start+n2.find_first("c:length").content.to_i) end Name.new( :name => name, :hash => hash, :type => type, :locations => locations ) end end def parse_relationships @libxml.root.find("rdf:Description/rdf:type[contains(@rdf:resource, '/em/r')]/..").each do |n| hash = n.properties.to_a.assoc("about").last.split("/").last type = n.find_first("rdf:type").properties.to_a.assoc("resource").last.split('/').last metadata = {} n.to_a.each do |n2| next if n2.name == "type" or n2.comment? resource = n2.properties.to_a.assoc("resource") metadata[n2.name] = resource ? Name.find_in_names(resource.last.split("/").last, @names) : n2.content.strip end locations = @libxml.root.find("rdf:Description/c:subject[contains(@rdf:resource, '#{hash}')]/..").map do |n2| start = n2.find_first("c:offset").content.to_i Range.new(start, start+n2.find_first("c:length").content.to_i) end @relationships << Relationship.new( :type => type, :hash => hash, :metadata => metadata, :locations => locations ) end end end end