Skip to content

Commit

Permalink
Now using RDF::Literal instead of RDFObject::Literal, rdfa_parser for…
Browse files Browse the repository at this point in the history
… RDFa and JSON serialization
  • Loading branch information
rsinger committed Jun 3, 2010
1 parent 925f673 commit 82f9e25
Show file tree
Hide file tree
Showing 11 changed files with 824 additions and 104 deletions.
4 changes: 3 additions & 1 deletion Rakefile.rb
Expand Up @@ -23,7 +23,9 @@
gemspec.authors = ["Ross Singer"]
gemspec.add_dependency('nokogiri')
gemspec.add_dependency('curies')
gemspec.add_dependency('addressable')
gemspec.add_dependency('addressable')
gemspec.add_dependency('rdf')
gemspec.add_dependency('rdfa_parser')
gemspec.requirements << 'json, json_pure or json-ruby required for parsing RDF/JSON'
gemspec.files = Dir.glob("{lib,spec}/**/*") + ["README", "LICENSE"]
gemspec.require_path = 'lib'
Expand Down
3 changes: 2 additions & 1 deletion lib/rdf_objects.rb
Expand Up @@ -2,11 +2,12 @@ module RDFObject
require 'rubygems'
require 'ostruct'
require 'curies'
require 'rdf'
require 'rdfa_parser'
require 'addressable/uri'
require File.dirname(__FILE__) + '/rdf_objects/parsers'
require File.dirname(__FILE__) + '/rdf_objects/rdf_resource'
require File.dirname(__FILE__) + '/rdf_objects/curies'
require File.dirname(__FILE__) + '/rdf_objects/data_types'
require File.dirname(__FILE__) + '/rdf_objects/http_client'
require File.dirname(__FILE__) + '/rdf_objects/collection'
Curie.remove_prefixes!(:http)
Expand Down
10 changes: 9 additions & 1 deletion lib/rdf_objects/collection.rb
Expand Up @@ -90,6 +90,14 @@ def to_xml(depth=0)
rdf << rdf_data
rdf << "</rdf:RDF>"
rdf
end
end
def to_json
j_hash = {}
self.values.each do |resource|
j_hash.merge!(resource.to_json_hash)
end
JSON.generate(j_hash)
end
end
end
39 changes: 23 additions & 16 deletions lib/rdf_objects/parsers.rb
Expand Up @@ -207,12 +207,13 @@ def parse_ntriple(ntriple)
scanner.getch
language = scanner.scan_until(/\s?\.\n?$/)
language.sub!(/\s?\.\n?$/,'')
language = language.to_sym
elsif scanner.match?(/\^\^/)
scanner.skip_until(/</)
data_type = scanner.scan_until(/>/)
data_type.sub!(/>$/,'')
end
object = Literal.new(tmp_object,{:data_type=>data_type,:language=>language})
object = RDF::Literal.new(tmp_object,{:datatype=>data_type,:language=>language})
type = "literal"
end
{:subject=>subject, :predicate=>predicate, :object=>object, :type=>type}
Expand Down Expand Up @@ -335,8 +336,10 @@ def attributes_as_assertions(attributes)
"http://www.w3.org/1999/02/22-rdf-syntax-ns#nodeID", "http://www.w3.org/1999/02/22-rdf-syntax-ns#datatype"]
attributes.each_pair do | uri, value |
next if skip.index(uri)
lit = Literal.new(value, {:data_type=>attributes["http://www.w3.org/1999/02/22-rdf-syntax-ns#datatype"],
:language=>attributes["http://www.w3.org/XML/1998/namespace/lang"]})
lit = RDF::Literal.new(value, {:datatype=>attributes["http://www.w3.org/1999/02/22-rdf-syntax-ns#datatype"]})
if attributes["http://www.w3.org/XML/1998/namespace/lang"]
lit.language = attributes["http://www.w3.org/XML/1998/namespace/lang"].to_sym
end
self.current_resource.assert(uri, lit)
end
end
Expand Down Expand Up @@ -365,7 +368,7 @@ def add_layer name, attributes, prefix, uri, ns
end
if attributes["http://www.w3.org/1999/02/22-rdf-syntax-ns#datatype"] || attributes["http://www.w3.org/XML/1998/namespace/lang"]
layer[:datatype] = attributes["http://www.w3.org/1999/02/22-rdf-syntax-ns#datatype"] if attributes["http://www.w3.org/1999/02/22-rdf-syntax-ns#datatype"]
layer[:language] = attributes["http://www.w3.org/XML/1998/namespace/lang"] if attributes["http://www.w3.org/XML/1998/namespace/lang"]
layer[:language] = attributes["http://www.w3.org/XML/1998/namespace/lang"].to_sym if attributes["http://www.w3.org/XML/1998/namespace/lang"]
end
layer[:base_uri] = Addressable::URI.parse(attributes["http://www.w3.org/XML/1998/namespace/base"]).normalize if attributes["http://www.w3.org/XML/1998/namespace/base"]
@hierarchy << layer
Expand All @@ -381,7 +384,7 @@ def remove_layer(name)
end

def assert_literal(layer)
lit = RDFObject::Literal.new(layer[:literal], {:data_type=>layer[:datatype], :language=>layer[:language]})
lit = RDF::Literal.new(layer[:literal], {:datatype=>layer[:datatype], :language=>layer[:language]})
self.current_resource.assert(layer[:predicate], lit) if layer[:predicate]
end

Expand Down Expand Up @@ -440,16 +443,20 @@ def end_element_namespace name, prefix = nil, uri = nil
end
end

class RDFAParser < XMLParser
class RDFAParser < Parser
def data=(xhtml)
if xhtml.is_a?(Nokogiri::XML::Document)
doc = xhtml
else
doc = Nokogiri::XML.parse(xhtml)
end
xslt = Nokogiri::XSLT(open(File.dirname(__FILE__) + '/../xsl/RDFa2RDFXML.xsl'))
@rdfxml = xslt.apply_to(doc)
@rdfa = xhtml
end

def parse
rdfa_parser = RdfaParser::RdfaParser.new()
html = open(uri)
ntriples = ""
rdfa_parser.parse(@rdfa, base_uri).each do | triple |
ntriples << triple.to_ntriples + "\n"
end
RDFObject::Parser.parse(ntriples)
end
end

class JSONParser < RDFObject::Parser
Expand All @@ -472,12 +479,12 @@ def parse
if object['type'] == 'literal'
opts = {}
if object['lang']
opts[:language] = object['lang']
opts[:language] = object['lang'].to_sym
end
if object['datatype']
opts[:data_type] = object['datatype']
opts[:datatype] = object['datatype']
end
literal = Literal.new(object['value'],opts)
literal = RDF::Literal.new(object['value'],opts)
resource.assert(predicate, literal)
elsif object['type'] == 'uri'
o = @collection.find_or_create(object['value'])
Expand Down
105 changes: 64 additions & 41 deletions lib/rdf_objects/rdf_resource.rb
Expand Up @@ -14,6 +14,8 @@ def assert(predicate, object)
pred_attr = self.send(curied_predicate.prefix.to_sym)
if object.is_a?(Resource)
object = ResourceReference.new(object)
elsif !object.is_a?(ResourceReference) && !object.is_a?(BlankNode)
object = RDF::Literal.new(object) unless object.is_a?(RDF::Literal)
end
return if assertion_exists?(predicate, object)
if pred_attr[curied_predicate.reference]
Expand All @@ -24,7 +26,8 @@ def assert(predicate, object)
else
pred_attr[curied_predicate.reference] = object
end
end
end


def assertion_exists?(predicate, object)
return false unless self[predicate]
Expand Down Expand Up @@ -115,15 +118,10 @@ def to_ntriples
if object.is_a?(ResourceReference) || object.is_a?(BlankNode)
line << object.ntriples_format
else
line << "#{object.to_json}"
if (object.respond_to?(:data_type) || object.respond_to?(:language))
if object.data_type
line << "^^<#{object.data_type}>"
end
if object.language
line << "@#{object.language}"
end
end
object = RDF::Literal.new(object) unless object.is_a?(RDF::Literal)
line << "#{object.value.to_json}"
line << "^^<#{object.datatype}>" if object.has_datatype?
line << "@#{object.language}" if object.has_language?
end
line << " .\n"
ntriples << line
Expand Down Expand Up @@ -151,6 +149,40 @@ def to_xml(depth=0)
rdf
end
def to_json_hash
j_hash = {self.uri=>{}}
self.assertions.each_pair do |pred,objects|
j_hash[self.uri][pred] = []
if objects.is_a?(Array)
objects.each do |object|
j_hash[self.uri][pred] << object_to_json_hash(object)
end
else
j_hash[self.uri][pred] << object_to_json_hash(objects)
end
end
j_hash
end
def object_to_json_hash(object)
if object.is_a?(Resource) or object.is_a?(ResourceReference)
o = {:type=>"uri", :value=>object.uri}
elsif object.is_a?(BlankNode)
o = {:type=>"bnode", :value=>object.uri}
else
object = RDF::Literal.new(object) unless object.is_a?(RDF::Literal)
o = {:type=>"literal", :value=>object.value}
o[:lang] = object.language.to_s if object.has_language?
o[:datatype] = object.datatype.to_s if object.has_datatype?
end
o
end
def to_json
JSON.generate(to_json_hash)
end
def rdf_description_block(depth=0)
rdf = "<rdf:Description #{xml_subject_attribute}>"
namespaces = {}
Expand All @@ -171,13 +203,14 @@ def rdf_description_block(depth=0)
rdf << "</#{key}:#{predicate}>"
end
else
object = RDF::Literal.new(object) unless object.is_a?(RDF::Literal)
if object.language
rdf << " xml:lang=\"#{object.language}\""
end
if object.data_type
rdf << " rdf:datatype=\"#{object.data_type}\""
if object.datatype
rdf << " rdf:datatype=\"#{object.datatype}\""
end
rdf << ">#{CGI.escapeHTML(object.to_s)}</#{key}:#{predicate}>"
rdf << ">#{CGI.escapeHTML(object.value)}</#{key}:#{predicate}>"
end
end
end
Expand All @@ -190,39 +223,29 @@ def rdf_description_block(depth=0)
def ==(other)
return false unless other.is_a?(self.class) or other.is_a?(ResourceReference)
return false unless self.uri == other.uri
Curie.get_mappings.each do | prefix, uri |
next unless self[uri] or other[uri]
return false if self[uri] && !other[uri]
return false if !self[uri] && other[uri]
return false if self[uri].class != other[uri].class
if self[uri] != other[uri]
if self[uri].is_a?(Hash)
return false unless self[uri].keys.eql?(other[uri].keys)
self[uri].keys.each do | pred |
if self[uri][pred].is_a?(Array)
return false unless self[uri][pred].length == other[uri][pred].length
self[uri][pred].each do | idx |
return false unless other[uri][pred].index(idx)
end
other[uri][pred].each do | idx |
return false unless self[uri][pred].index(idx)
end
else
if self[uri][pred].is_a?(Resource) or self[uri][pred].is_a?(BlankNode) or self[uri][pred].is_a?(ResourceReference)
return false unless other[uri][pred].is_a?(Resource) or self[uri][pred].is_a?(BlankNode) or other[uri][pred].is_a?(ResourceReference)
return false unless self[uri][pred].uri == other[uri][pred].uri
else
return false unless self[uri][pred] == other[uri][pred]
end
end
return false unless self.assertions.keys.sort == other.assertions.keys.sort
self.assertions.each_pair do |pred, objects|
return false if objects.class != other[pred].class
objects = [objects] unless objects.is_a?(Array)
objects.each do | o |
match = false
[*other[pred]].each do |oo|
next unless oo
next unless o.class == oo.class
if oo.is_a?(RDF::Literal)
match = o == oo
else
match = o.uri == oo.uri
end
else
return false
break if match
end
return false unless match
end
end
true
return true
end
end
class Resource < OpenStruct
Expand Down

0 comments on commit 82f9e25

Please sign in to comment.