tommorris-rena 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.txt +48 -0
- data/Rakefile +50 -0
- data/lib/rena/bnode.rb +63 -0
- data/lib/rena/exceptions/about_each_exception.rb +2 -0
- data/lib/rena/exceptions/uri_relative_exception.rb +2 -0
- data/lib/rena/graph.rb +150 -0
- data/lib/rena/literal.rb +89 -0
- data/lib/rena/namespace.rb +74 -0
- data/lib/rena/rdfxmlparser.rb +182 -0
- data/lib/rena/rexml_hacks.rb +70 -0
- data/lib/rena/triple.rb +72 -0
- data/lib/rena/uriref.rb +41 -0
- data/lib/rena.rb +5 -0
- data/rena.gemspec +16 -0
- data/test/spec/bnode.spec.rb +25 -0
- data/test/spec/graph.spec.rb +108 -0
- data/test/spec/literal.spec.rb +112 -0
- data/test/spec/namespaces.spec.rb +44 -0
- data/test/spec/parser.spec.rb +288 -0
- data/test/spec/rexml_hacks.spec.rb +76 -0
- data/test/spec/triple.spec.rb +32 -0
- data/test/spec/uriref.spec.rb +47 -0
- data/test/test_uris.rb +13 -0
- data/test/xml.rdf +6 -0
- metadata +84 -0
data/README.txt
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
= rena
|
2
|
+
|
3
|
+
* http://github.com/tommorris/rena
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
Rena is an RDF library for Ruby.
|
8
|
+
|
9
|
+
== FEATURES/PROBLEMS:
|
10
|
+
|
11
|
+
* Features
|
12
|
+
|
13
|
+
== SYNOPSIS:
|
14
|
+
|
15
|
+
Synopsis
|
16
|
+
|
17
|
+
== REQUIREMENTS:
|
18
|
+
|
19
|
+
* Addressable gem
|
20
|
+
|
21
|
+
== INSTALL:
|
22
|
+
|
23
|
+
* (sudo gem install rena)
|
24
|
+
|
25
|
+
== LICENSE:
|
26
|
+
|
27
|
+
(The MIT License)
|
28
|
+
|
29
|
+
Copyright (c) 2008 Tom Morris
|
30
|
+
|
31
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
32
|
+
a copy of this software and associated documentation files (the
|
33
|
+
'Software'), to deal in the Software without restriction, including
|
34
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
35
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
36
|
+
permit persons to whom the Software is furnished to do so, subject to
|
37
|
+
the following conditions:
|
38
|
+
|
39
|
+
The above copyright notice and this permission notice shall be
|
40
|
+
included in all copies or substantial portions of the Software.
|
41
|
+
|
42
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
43
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
44
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
45
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
46
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
47
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
48
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'spec/rake/spectask'
|
4
|
+
|
5
|
+
task :default => [:spec]
|
6
|
+
|
7
|
+
desc "Install dependencies"
|
8
|
+
task :dependencies do
|
9
|
+
require ''
|
10
|
+
gems = ['addressable/uri']
|
11
|
+
gems.each do |g|
|
12
|
+
g2 = g.split('/')[0]
|
13
|
+
begin
|
14
|
+
require g2
|
15
|
+
rescue
|
16
|
+
sh "sudo gem install " + g2
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
desc "Pushes to git"
|
22
|
+
task :push do
|
23
|
+
sh "git push --all"
|
24
|
+
sh "growlnotify -m \"Updates pushed\" \"Git\""
|
25
|
+
end
|
26
|
+
|
27
|
+
desc "Runs specs"
|
28
|
+
task :spec do
|
29
|
+
sh "spec --colour --pattern test/spec/*.spec.rb"
|
30
|
+
end
|
31
|
+
|
32
|
+
desc "Turns spec results into HTML and publish to web (Tom only!)"
|
33
|
+
task :spec_html do
|
34
|
+
sh "spec --pattern test/spec/*.spec.rb --format html:rena_new_spec.html"
|
35
|
+
sh "scp rena_new_spec.html bbcityco@bbcity.co.uk:www/tom/files/rena_new_spec.html"
|
36
|
+
sh "rm rena_new_spec.html"
|
37
|
+
end
|
38
|
+
|
39
|
+
desc "Turns spec results into local HTML"
|
40
|
+
task :spec_local do
|
41
|
+
sh "spec --pattern test/spec/*.spec.rb --format html:rena_new_spec.html"
|
42
|
+
# sh "open rena_new_spec.html"
|
43
|
+
end
|
44
|
+
|
45
|
+
desc "Run specs through RCov"
|
46
|
+
Spec::Rake::SpecTask.new('coverage') do |t|
|
47
|
+
t.spec_files = FileList['test/spec/**/*.rb']
|
48
|
+
t.rcov = true
|
49
|
+
t.rcov_opts = ['--exclude', 'test,\/Library\/Ruby\/Gems\/1.8\/gems']
|
50
|
+
end
|
data/lib/rena/bnode.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
class BNode
|
2
|
+
attr_accessor :identifier
|
3
|
+
def initialize(identifier = nil)
|
4
|
+
if identifier != nil && self.valid_id?(identifier) != false
|
5
|
+
@identifier = identifier
|
6
|
+
else
|
7
|
+
@identifier = "bn" + self.hash.to_s
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def eql? (eql)
|
12
|
+
if self.identifier == eql.identifier
|
13
|
+
true
|
14
|
+
else
|
15
|
+
false
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
##
|
20
|
+
# Exports the BNode in N-Triples form.
|
21
|
+
#
|
22
|
+
# ==== Example
|
23
|
+
# b = BNode.new; b.to_n3 # => returns a string of the BNode in n3 form
|
24
|
+
#
|
25
|
+
# ==== Returns
|
26
|
+
# @return [String] The BNode in n3.
|
27
|
+
#
|
28
|
+
# @author Tom Morris
|
29
|
+
|
30
|
+
def to_n3
|
31
|
+
"_:" + @identifier
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
##
|
36
|
+
# Exports the BNode in N-Triples form.
|
37
|
+
#
|
38
|
+
# ==== Example
|
39
|
+
# b = BNode.new; b.to_ntriples # => returns a string of the BNode in N-Triples form
|
40
|
+
#
|
41
|
+
# ==== Returns
|
42
|
+
# @return [String] The BNode in N-Triples.
|
43
|
+
#
|
44
|
+
# @author Tom Morris
|
45
|
+
|
46
|
+
def to_ntriples
|
47
|
+
self.to_n3
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_s
|
51
|
+
@identifier
|
52
|
+
end
|
53
|
+
|
54
|
+
# TODO: add valid bnode name exceptions?
|
55
|
+
protected
|
56
|
+
def valid_id? name
|
57
|
+
if name =~ /^[a-zA-Z_][a-zA-Z0-9]*$/
|
58
|
+
true
|
59
|
+
else
|
60
|
+
false
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/rena/graph.rb
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
require 'rena/namespace'
|
2
|
+
require 'rena/bnode'
|
3
|
+
require 'rena/uriref'
|
4
|
+
require 'rena/literal'
|
5
|
+
require 'rena/triple'
|
6
|
+
|
7
|
+
class Graph
|
8
|
+
attr_accessor :triples, :nsbinding
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@triples = []
|
12
|
+
@nsbinding = {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def size
|
16
|
+
@triples.size
|
17
|
+
end
|
18
|
+
|
19
|
+
def each
|
20
|
+
@triples.each { |value| yield value }
|
21
|
+
end
|
22
|
+
|
23
|
+
def each_with_subject(subject)
|
24
|
+
@triples.each {|value|
|
25
|
+
if value.subject == subject
|
26
|
+
yield value
|
27
|
+
end
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
##
|
32
|
+
# Adds a triple to a graph directly from the intended subject, predicate, and object.
|
33
|
+
#
|
34
|
+
# ==== Example
|
35
|
+
# g = Graph.new; g.add_triple(BNode.new, URIRef.new("http://xmlns.com/foaf/0.1/knows"), BNode.new) # => results in the triple being added to g; returns an array of g's triples
|
36
|
+
#
|
37
|
+
# @param [URIRef, BNode] s the subject of the triple
|
38
|
+
# @param [URIRef] p the predicate of the triple
|
39
|
+
# @param [URIRef, BNode, Literal, TypedLiteral] o the object of the triple
|
40
|
+
#
|
41
|
+
# ==== Returns
|
42
|
+
# @return [Array] An array of the triples (leaky abstraction? consider returning the graph instead)
|
43
|
+
#
|
44
|
+
# @raise [Error] Checks parameter types and raises if they are incorrect.
|
45
|
+
# @author Tom Morris
|
46
|
+
|
47
|
+
def add_triple(s, p, o)
|
48
|
+
@triples += [ Triple.new(s, p, o) ]
|
49
|
+
end
|
50
|
+
|
51
|
+
##
|
52
|
+
# Adds an extant triple to a graph
|
53
|
+
#
|
54
|
+
# ==== Example
|
55
|
+
# g = Graph.new; t = Triple.new(BNode.new, URIRef.new("http://xmlns.com/foaf/0.1/knows"), BNode.new); g << t) # => results in the triple being added to g; returns an array of g's triples
|
56
|
+
#
|
57
|
+
# @param [Triple] t the triple to be added to the graph
|
58
|
+
#
|
59
|
+
# ==== Returns
|
60
|
+
# @return [Array] An array of the triples (leaky abstraction? consider returning the graph instead)
|
61
|
+
#
|
62
|
+
# @author Tom Morris
|
63
|
+
|
64
|
+
|
65
|
+
def << (triple)
|
66
|
+
# self.add_triple(s, p, o)
|
67
|
+
@triples += [ triple ]
|
68
|
+
end
|
69
|
+
|
70
|
+
##
|
71
|
+
# Exports the graph to RDF in N-Triples form.
|
72
|
+
#
|
73
|
+
# ==== Example
|
74
|
+
# g = Graph.new; g.add_triple(BNode.new, URIRef.new("http://xmlns.com/foaf/0.1/knows"), BNode.new); g.to_ntriples # => returns a string of the graph in N-Triples form
|
75
|
+
#
|
76
|
+
# ==== Returns
|
77
|
+
# @return [String] The graph in N-Triples.
|
78
|
+
#
|
79
|
+
# @author Tom Morris
|
80
|
+
|
81
|
+
def to_ntriples
|
82
|
+
str = ""
|
83
|
+
@triples.each do |t|
|
84
|
+
str << t.to_ntriples + "\n"
|
85
|
+
end
|
86
|
+
return str
|
87
|
+
end
|
88
|
+
|
89
|
+
##
|
90
|
+
# Creates a new namespace given a URI and the short name and binds it to the graph.
|
91
|
+
#
|
92
|
+
# ==== Example
|
93
|
+
# g = Graph.new; g.namespace("http://xmlns.com/foaf/0.1/", "foaf") # => binds the Foaf namespace to g
|
94
|
+
#
|
95
|
+
# @param [String] uri the URI of the namespace
|
96
|
+
# @param [String] short the short name of the namespace
|
97
|
+
#
|
98
|
+
# ==== Returns
|
99
|
+
# @return [Namespace] The newly created namespace.
|
100
|
+
#
|
101
|
+
# @raise [Error] Checks validity of the desired shortname and raises if it is incorrect.
|
102
|
+
# @raise [Error] Checks that the newly created Namespace is of type Namespace and raises if it is incorrect.
|
103
|
+
# @author Tom Morris
|
104
|
+
|
105
|
+
def namespace(uri, short)
|
106
|
+
self.bind Namespace.new(uri, short)
|
107
|
+
end
|
108
|
+
|
109
|
+
def bind(namespace)
|
110
|
+
if namespace.class == Namespace
|
111
|
+
@nsbinding["#{namespace.short}"] = namespace
|
112
|
+
else
|
113
|
+
raise
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def has_bnode_identifier?(bnodeid)
|
118
|
+
temp_bnode = BNode.new(bnodeid)
|
119
|
+
returnval = false
|
120
|
+
@triples.each { |triple|
|
121
|
+
if triple.subject.eql?(temp_bnode)
|
122
|
+
returnval = true
|
123
|
+
break
|
124
|
+
end
|
125
|
+
if triple.object.eql?(temp_bnode)
|
126
|
+
returnval = true
|
127
|
+
break
|
128
|
+
end
|
129
|
+
}
|
130
|
+
return returnval
|
131
|
+
end
|
132
|
+
|
133
|
+
def get_bnode_by_identifier(bnodeid)
|
134
|
+
temp_bnode = BNode.new(bnodeid)
|
135
|
+
returnval = false
|
136
|
+
@triples.each { |triple|
|
137
|
+
if triple.subject.eql?(temp_bnode)
|
138
|
+
returnval = triple.subject
|
139
|
+
break
|
140
|
+
end
|
141
|
+
if triple.object.eql?(temp_bnode)
|
142
|
+
returnval = triple.object
|
143
|
+
break
|
144
|
+
end
|
145
|
+
}
|
146
|
+
return returnval
|
147
|
+
end
|
148
|
+
# alias :add, :add_triple
|
149
|
+
# alias (=+, add_triple)
|
150
|
+
end
|
data/lib/rena/literal.rb
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
class Literal
|
2
|
+
attr_accessor :contents, :lang
|
3
|
+
def initialize(contents, lang = nil)
|
4
|
+
@contents = contents
|
5
|
+
if lang != nil && lang != false
|
6
|
+
@lang = lang.downcase
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def == (obj)
|
11
|
+
if obj.class == Literal && obj.contents == @contents && (obj.lang == @lang || (obj.lang == nil && @lang == nil))
|
12
|
+
true
|
13
|
+
else
|
14
|
+
false
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_n3
|
19
|
+
out = "\"" + @contents + "\""
|
20
|
+
out += "@" + @lang if @lang != nil
|
21
|
+
out += "^^" + @encoding if @encoding != nil
|
22
|
+
return out
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_ntriples
|
26
|
+
return self.to_n3
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_trix
|
30
|
+
if @lang != nil && @lang != false
|
31
|
+
out = "<plainLiteral xml:lang=\"" + @lang + "\">"
|
32
|
+
else
|
33
|
+
out = "<plainLiteral>"
|
34
|
+
end
|
35
|
+
out += @contents
|
36
|
+
out += "</plainLiteral>"
|
37
|
+
return out
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
class TypedLiteral < Literal
|
43
|
+
attr_accessor :contents, :encoding
|
44
|
+
def initialize(contents, encoding)
|
45
|
+
@contents = contents
|
46
|
+
@encoding = encoding
|
47
|
+
if @encoding == "http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral"
|
48
|
+
@xmlliteral = true
|
49
|
+
else
|
50
|
+
@xmlliteral = false
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def == (obj)
|
55
|
+
if obj.class == TypedLiteral && obj.contents == @contents && obj.encoding == @encoding
|
56
|
+
return true
|
57
|
+
else
|
58
|
+
return false
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def to_n3
|
63
|
+
if @encoding == "http://www.w3.org/2001/XMLSchema#int"
|
64
|
+
out = @contents.to_s
|
65
|
+
else
|
66
|
+
out = "\"" + @contents.to_s + "\""
|
67
|
+
end
|
68
|
+
out += "^^<" + @encoding + ">" if @encoding != nil
|
69
|
+
return out
|
70
|
+
end
|
71
|
+
|
72
|
+
def to_trix
|
73
|
+
"<typedLiteral datatype=\"" + @encoding + "\">" + @contents + "</typedLiteral>"
|
74
|
+
end
|
75
|
+
|
76
|
+
def xmlliteral?
|
77
|
+
@xmlliteral
|
78
|
+
end
|
79
|
+
|
80
|
+
def infer!
|
81
|
+
if @contents.class == Fixnum
|
82
|
+
@encoding = "http://www.w3.org/2001/XMLSchema#int"
|
83
|
+
elsif @contents.class == Float
|
84
|
+
@encoding = "http://www.w3.org/2001/XMLSchema#float"
|
85
|
+
else
|
86
|
+
@encoding = "http://www.w3.org/2001/XMLSchema#string"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'rena/uriref'
|
2
|
+
require 'rena/graph'
|
3
|
+
|
4
|
+
class Namespace
|
5
|
+
attr_accessor :short, :uri, :fragment
|
6
|
+
|
7
|
+
##
|
8
|
+
# Creates a new namespace given a URI and the short name.
|
9
|
+
#
|
10
|
+
# ==== Example
|
11
|
+
# Namespace.new("http://xmlns.com/foaf/0.1/", "foaf") # => returns a new Foaf namespace
|
12
|
+
#
|
13
|
+
# @param [String] uri the URI of the namespace
|
14
|
+
# @param [String] short the short name of the namespace
|
15
|
+
# @param [Boolean] fragment are the identifiers on this resource fragment identifiers? (e.g. '#') Defaults to false.
|
16
|
+
#
|
17
|
+
# ==== Returns
|
18
|
+
# @return [Namespace] The newly created namespace.
|
19
|
+
#
|
20
|
+
# @raise [Error] Checks validity of the desired shortname and raises if it is incorrect.
|
21
|
+
# @author Tom Morris, Pius Uzamere
|
22
|
+
|
23
|
+
def initialize(uri, short, fragment = false)
|
24
|
+
@uri = uri
|
25
|
+
@fragment = fragment
|
26
|
+
if shortname_valid?(short)
|
27
|
+
@short = short
|
28
|
+
else
|
29
|
+
raise
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
##
|
34
|
+
# Allows the construction of arbitrary URIs on the namespace.
|
35
|
+
#
|
36
|
+
# ==== Example
|
37
|
+
# foaf = Namespace.new("http://xmlns.com/foaf/0.1/", "foaf"); foaf.knows # => returns a new URIRef with URI "http://xmlns.com/foaf/0.1/knows"
|
38
|
+
# foaf = Namespace.new("http://xmlns.com/foaf/0.1/", "foaf", true); foaf.knows # => returns a new URIRef with URI "http://xmlns.com/foaf/0.1/#knows"
|
39
|
+
#
|
40
|
+
# @param [String] uri the URI of the namespace
|
41
|
+
# @param [String] short the short name of the namespace
|
42
|
+
# @param [Boolean] fragment are the identifiers on this resource fragment identifiers? (e.g. '#') Defaults to false.
|
43
|
+
#
|
44
|
+
# ==== Returns
|
45
|
+
# @return [URIRef] The newly created URIRegerence.
|
46
|
+
#
|
47
|
+
# @raise [Error] Checks validity of the desired shortname and raises if it is incorrect.
|
48
|
+
# @author Tom Morris, Pius Uzamere
|
49
|
+
|
50
|
+
def method_missing(methodname, *args)
|
51
|
+
unless fragment
|
52
|
+
URIRef.new(@uri + methodname.to_s)
|
53
|
+
else
|
54
|
+
URIRef.new(@uri + '#' + methodname.to_s)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def bind(graph)
|
59
|
+
if graph.class == Graph
|
60
|
+
graph.bind(self)
|
61
|
+
else
|
62
|
+
raise
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
def shortname_valid?(shortname)
|
68
|
+
if shortname =~ /[a-zA-Z_][a-zA-Z0-9_]+/
|
69
|
+
return true
|
70
|
+
else
|
71
|
+
return false
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,182 @@
|
|
1
|
+
require 'rena/uriref'
|
2
|
+
require 'rena/graph'
|
3
|
+
require 'rena/literal'
|
4
|
+
require 'rena/exceptions/uri_relative_exception'
|
5
|
+
require 'rena/exceptions/about_each_exception'
|
6
|
+
require 'rena/rexml_hacks'
|
7
|
+
|
8
|
+
class RdfXmlParser
|
9
|
+
attr_accessor :xml, :graph
|
10
|
+
def initialize (xml_str, uri = nil)
|
11
|
+
@excl = ["http://www.w3.org/1999/02/22-rdf-syntax-ns#resource", "http://www.w3.org/1999/02/22-rdf-syntax-ns#nodeID", "http://www.w3.org/1999/02/22-rdf-syntax-ns#about", "http://www.w3.org/1999/02/22-rdf-syntax-ns#ID"]
|
12
|
+
if uri != nil
|
13
|
+
@uri = Addressable::URI.parse(uri)
|
14
|
+
end
|
15
|
+
@xml = REXML::Document.new(xml_str)
|
16
|
+
# self.iterator @xml.root.children
|
17
|
+
if self.is_rdf?
|
18
|
+
@graph = Graph.new
|
19
|
+
@xml.root.each_element { |e|
|
20
|
+
self.parse_element e
|
21
|
+
}
|
22
|
+
# puts @graph.size
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def is_rdf?
|
27
|
+
trigger = false
|
28
|
+
@xml.each_element do |e|
|
29
|
+
if e.namespaces.has_value? "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
30
|
+
trigger = true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
return trigger
|
34
|
+
end
|
35
|
+
|
36
|
+
protected
|
37
|
+
def get_uri_from_atts (element, aboutmode = false)
|
38
|
+
if aboutmode == false
|
39
|
+
resourceuri = "http://www.w3.org/1999/02/22-rdf-syntax-ns#resource"
|
40
|
+
else
|
41
|
+
resourceuri = "http://www.w3.org/1999/02/22-rdf-syntax-ns#about"
|
42
|
+
end
|
43
|
+
|
44
|
+
subject = nil
|
45
|
+
element.attributes.each_attribute { |att|
|
46
|
+
uri = att.namespace + att.name
|
47
|
+
value = att.to_s
|
48
|
+
if uri == "http://www.w3.org/1999/02/22-rdf-syntax-ns#aboutEach"
|
49
|
+
raise AboutEachException, "Failed as per RDFMS-AboutEach-Error001.rdf test from 2004 test suite"
|
50
|
+
end
|
51
|
+
if uri == "http://www.w3.org/1999/02/22-rdf-syntax-ns#aboutEachPrefix"
|
52
|
+
raise AboutEachException, "Failed as per RDFMS-AboutEach-Error002.rdf test from 2004 test suite"
|
53
|
+
end
|
54
|
+
if uri == "http://www.w3.org/1999/02/22-rdf-syntax-ns#bagID"
|
55
|
+
raise
|
56
|
+
if name =~ /^[a-zA-Z_][a-zA-Z0-9]*$/
|
57
|
+
# TODO: do something intelligent with the bagID
|
58
|
+
else
|
59
|
+
raise
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
if uri == resourceuri #specified resource
|
64
|
+
begin
|
65
|
+
possible_subject = URIRef.new(value)
|
66
|
+
rescue UriRelativeException
|
67
|
+
if value[0..0].to_s != "#"
|
68
|
+
value = "#" + value
|
69
|
+
end
|
70
|
+
begin
|
71
|
+
value = URIRef.new(element.base + value)
|
72
|
+
rescue UriRelativeException
|
73
|
+
# still not a URI
|
74
|
+
raise
|
75
|
+
else
|
76
|
+
subject = value
|
77
|
+
end
|
78
|
+
else
|
79
|
+
subject = possible_subject
|
80
|
+
break
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
if uri == "http://www.w3.org/1999/02/22-rdf-syntax-ns#nodeID" #BNode with ID
|
85
|
+
# we have a BNode with an identifier. First, we need to do syntax checking.
|
86
|
+
if value =~ /^[a-zA-Z_][a-zA-Z0-9]*$/
|
87
|
+
# now we check to see if the graph has the value
|
88
|
+
if @graph.has_bnode_identifier?(value)
|
89
|
+
# if so, pull it in - no need to recreate objects.
|
90
|
+
subject = @graph.get_bnode_by_identifier(value)
|
91
|
+
else
|
92
|
+
# if not, create a new one.
|
93
|
+
subject = BNode.new(value)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
if uri == "http://www.w3.org/1999/02/22-rdf-syntax-ns#ID"
|
99
|
+
begin
|
100
|
+
# check for base
|
101
|
+
if att.element.base?
|
102
|
+
subject = att.element.base.to_s + value
|
103
|
+
elsif @uri != nil
|
104
|
+
compound = @uri.to_s + "#" + value
|
105
|
+
subject = compound.to_s
|
106
|
+
else
|
107
|
+
raise "Needs to have an ID"
|
108
|
+
end
|
109
|
+
# rescue UriRelativeException
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# add other subject detection subroutines here
|
114
|
+
}
|
115
|
+
if subject.class == NilClass
|
116
|
+
subject = BNode.new
|
117
|
+
end
|
118
|
+
return subject
|
119
|
+
end
|
120
|
+
|
121
|
+
protected
|
122
|
+
def parse_element (element, subject = nil, resource = false)
|
123
|
+
if subject == nil
|
124
|
+
# figure out subject
|
125
|
+
subject = self.get_uri_from_atts(element, true)
|
126
|
+
end
|
127
|
+
|
128
|
+
# type parsing
|
129
|
+
if resource == true
|
130
|
+
type = URIRef.new(element.namespace + element.name)
|
131
|
+
unless type.to_s == "http://www.w3.org/1999/02/22-rdf-syntax-ns#Description"
|
132
|
+
@graph.add_triple(subject, URIRef.new("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"), type)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
# attribute parsing
|
137
|
+
element.attributes.each_attribute { |att|
|
138
|
+
uri = att.namespace + att.name
|
139
|
+
value = att.to_s
|
140
|
+
|
141
|
+
unless @excl.member? uri
|
142
|
+
@graph.add_triple(subject, URIRef.new(uri), Literal.new(value))
|
143
|
+
end
|
144
|
+
}
|
145
|
+
|
146
|
+
# element parsing
|
147
|
+
element.each_element { |e|
|
148
|
+
self.parse_resource_element e, subject
|
149
|
+
}
|
150
|
+
end
|
151
|
+
|
152
|
+
def parse_resource_element e, subject
|
153
|
+
uri = e.namespace + e.name
|
154
|
+
if e.attributes.get_attribute_ns("http://www.w3.org/1999/02/22-rdf-syntax-ns#", "parseType").to_s == "Literal"
|
155
|
+
@graph.add_triple(subject, URIRef.new(uri), TypedLiteral.new(e.children.to_s.strip, "http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral"))
|
156
|
+
elsif e.has_elements?
|
157
|
+
# subparsing
|
158
|
+
e.each_element { |se| #se = 'striped element'
|
159
|
+
if e.attributes.get_attribute_ns("http://www.w3.org/1999/02/22-rdf-syntax-ns#", "parseType").to_s == "Resource"
|
160
|
+
object = BNode.new
|
161
|
+
else
|
162
|
+
object = self.get_uri_from_atts(se, true)
|
163
|
+
end
|
164
|
+
@graph.add_triple(subject, URIRef.new(uri), object)
|
165
|
+
self.parse_element(se, object, true)
|
166
|
+
}
|
167
|
+
elsif e.attributes.get_attribute_ns("http://www.w3.org/1999/02/22-rdf-syntax-ns#", "datatype")
|
168
|
+
@graph.add_triple(subject, URIRef.new(uri), TypedLiteral.new(e.text, e.attributes.get_attribute_ns("http://www.w3.org/1999/02/22-rdf-syntax-ns#", "datatype").to_s.strip))
|
169
|
+
elsif e.has_attributes?
|
170
|
+
# get object out
|
171
|
+
object = self.get_uri_from_atts(e)
|
172
|
+
@graph.add_triple(subject, URIRef.new(uri), object)
|
173
|
+
elsif e.has_text?
|
174
|
+
if e.lang?
|
175
|
+
@graph.add_triple(subject, URIRef.new(uri), Literal.new(e.text, e.lang))
|
176
|
+
else
|
177
|
+
@graph.add_triple(subject, URIRef.new(uri), Literal.new(e.text))
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|