rdfobjects 0.6.6 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +41 -23
- data/lib/rdf_objects/collection.rb +54 -1
- data/lib/rdf_objects/rdf_resource.rb +118 -0
- metadata +2 -2
data/README
CHANGED
@@ -53,15 +53,25 @@ Usage:
|
|
53
53
|
|
54
54
|
=> "en"
|
55
55
|
|
56
|
-
To relate a resource to another URI you can use #.
|
56
|
+
To relate a resource to another URI you can use #.relate - it will accept full uri strings, safe curies or other RDFObject::Resource objects
|
57
57
|
|
58
58
|
>> resource.relate("[skos:closeMatch]", "http://dbpedia.org/resource/Category:Semantic_Web")
|
59
59
|
|
60
60
|
=> [#<RDFObject::Resource uri="http://stitch.cs.vu.nl/vocabularies/rameau/ark:/12148/cb14521343b">, #<RDFObject::Resource uri="http://dbpedia.org/resource/Category:Semantic_Web">]
|
61
61
|
|
62
|
-
RDFObject::
|
62
|
+
These relationships are actually replaced with RDFObject::ResourceReference objects (to prevent massive recursion errors). To access the actual Resource object, use:
|
63
63
|
|
64
|
-
>>
|
64
|
+
>> resource["[skos:closeMatch]"].first.resource
|
65
|
+
|
66
|
+
=> #<RDFObject::Resource uri="http://stitch.cs.vu.nl/vocabularies/rameau/ark:/12148/cb14521343b">
|
67
|
+
|
68
|
+
In order to be sure you are always asserting against the same object, use RDFObject::Collection objects to manage your Resources.
|
69
|
+
|
70
|
+
>> collection = Collection.new
|
71
|
+
|
72
|
+
=> {}
|
73
|
+
|
74
|
+
>> r1 = collection.find_or_create('http://ex.org/ex/1234')
|
65
75
|
|
66
76
|
=> #<RDFObject::Resource uri="http://ex.org/ex/1234">
|
67
77
|
|
@@ -69,7 +79,7 @@ Usage:
|
|
69
79
|
|
70
80
|
=> 8996290
|
71
81
|
|
72
|
-
>> r2 =
|
82
|
+
>> r2 = collection.find_or_create('http://ex.org/ex/1234')
|
73
83
|
|
74
84
|
=> #<RDFObject::Resource uri="http://ex.org/ex/1234">
|
75
85
|
|
@@ -77,38 +87,46 @@ Usage:
|
|
77
87
|
|
78
88
|
=> 8996290
|
79
89
|
|
80
|
-
So relationships and assertions are always applied to the same
|
90
|
+
So relationships and assertions are always applied to the same objects.
|
81
91
|
|
82
|
-
|
92
|
+
You can delete a single resource:
|
83
93
|
|
84
|
-
|
94
|
+
>> collection.remove(r1)
|
85
95
|
|
86
|
-
|
96
|
+
>> collection
|
97
|
+
=> {}
|
87
98
|
|
88
|
-
|
99
|
+
There is also a convenience method on RDFObject::Collection to help find particular resources by predicate:
|
89
100
|
|
90
|
-
|
101
|
+
>> resources_with_types = collection.find_by_predicate("http://www.w3.org/1999/02/22-rdf-syntax-ns#type")
|
91
102
|
|
92
|
-
|
103
|
+
And to find resources by predicate and object:
|
93
104
|
|
94
|
-
|
105
|
+
>> resources_i_want = collection.find_by_predicate_and_object("http://www.w3.org/2004/02/skos/core#closeMatch", "http://stitch.cs.vu.nl/vocabularies/rameau/ark:/12148/cb145537755")
|
95
106
|
|
96
|
-
|
107
|
+
Both these return RDFObject::Collection objects with your matches. Changes to resources in these collections also affect the resource in original collection.
|
97
108
|
|
98
|
-
|
109
|
+
There are also parsers for ntriples, rdf/xml, RSS 1.0, RDFa, and JSON. Parsers return a RDFObject::Collection with all of the resources discovered in the RDF source.
|
99
110
|
|
100
|
-
>>
|
101
|
-
=> {}
|
102
|
-
|
103
|
-
Or clear the entire hash:
|
111
|
+
>> resources = Parser.parse(open('lcsh.nt').read)
|
104
112
|
|
105
|
-
>>
|
113
|
+
>> resources.values.first
|
106
114
|
|
107
|
-
|
115
|
+
=> #<RDFObject::Resource n0={"altLabel"=>"Lichen ruber planus", "inScheme"=>[#<RDFObject::Resource uri="http://id.loc.gov/authorities#conceptScheme">, #<RDFObject::Resource uri="http://id.loc.gov/authorities#topicalTerms">], "prefLabel"=>"Lichen planus"}, n1={"sameAs"=>#<RDFObject::Resource uri="info:lc/authorities/sh85076767">}, uri="http://id.loc.gov/authorities/sh85076767#concept", n2={"modified"=>#<DateTime: 211644344801/86400,-1/6,2299161>}, rdf={"type"=>#<RDFObject::Resource uri="http://www.w3.org/2004/02/skos/core#Concept">}>
|
108
116
|
|
109
|
-
|
117
|
+
There are serializers for RDF/XML and ntriples. Both resources and collections can be serialized.
|
110
118
|
|
111
|
-
>>
|
119
|
+
>> resource.to_xml
|
112
120
|
|
113
|
-
=>
|
121
|
+
=> "<rdf:RDF xmlns:n0="http://www.w3.org/2004/02/skos/core#" xmlns:n1="http://www.w3.org/2002/07/owl#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:n2="http://purl.org/dc/terms/"><rdf:Description rdf:about="http://id.loc.gov/authorities/sh85076767#concept"><n0:altLabel>Lichen ruber planus</n0:altLabel><n0:inScheme><rdf:Description rdf:about="http://id.loc.gov/authorities#conceptScheme"></rdf:Description></n0:inScheme><n0:inScheme><rdf:Description rdf:about="http://id.loc.gov/authorities#topicalTerms"></rdf:Description></n0:inScheme><n0:prefLabel>Lichen planus</n0:prefLabel><n1:sameAs><rdf:Description rdf:about="info:lc/authorities/sh85076767"></rdf:Description></n1:sameAs><n2:modified rdf:datatype="http://www.w3.org/2001/XMLSchema#dateTime">1994-08-22T15:46:41-04:00</n2:modified><rdf:type><rdf:Description rdf:about="http://www.w3.org/2004/02/skos/core#Concept"></rdf:Description></rdf:type></rdf:Description></rdf:RDF>"
|
122
|
+
|
123
|
+
>> collection.to_xml
|
124
|
+
|
125
|
+
>> resource.to_ntriples
|
126
|
+
|
127
|
+
=> "<http://id.loc.gov/authorities/sh85076767#concept> <http://www.w3.org/2004/02/skos/core#altLabel> "Lichen ruber planus"@en.\n<http://id.loc.gov/authorities/sh85076767#concept> <http://www.w3.org/2004/02/skos/core#inScheme> <http://id.loc.gov/authorities#conceptScheme>.\n<http://id.loc.gov/authorities/sh85076767#concept> <http://www.w3.org/2004/02/skos/core#inScheme> <http://id.loc.gov/authorities#topicalTerms>.\n<http://id.loc.gov/authorities/sh85076767#concept> <http://www.w3.org/2004/02/skos/core#prefLabel> "Lichen planus"@en.\n<http://id.loc.gov/authorities/sh85076767#concept> <http://www.w3.org/2002/07/owl#sameAs> <info:lc/authorities/sh85076767>.\n<http://id.loc.gov/authorities/sh85076767#concept> <http://purl.org/dc/terms/modified> "1994-08-22T15:46:41-04:00"^^<http://www.w3.org/2001/XMLSchema#dateTime>.\n<http://id.loc.gov/authorities/sh85076767#concept> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2004/02/skos/core#Concept>.\n"
|
128
|
+
|
129
|
+
>> collection.to_ntriples
|
130
|
+
|
131
|
+
etc.
|
114
132
|
|
@@ -7,12 +7,34 @@ module RDFObject
|
|
7
7
|
if predicate.could_be_a_safe_curie?
|
8
8
|
predicate = Curie.parse predicate
|
9
9
|
end
|
10
|
-
self.find_all {|r|
|
10
|
+
matches = self.find_all {|r|
|
11
11
|
if r[1][predicate]
|
12
12
|
r[1]
|
13
13
|
end
|
14
14
|
}
|
15
|
+
resources = Collection.new
|
16
|
+
matches.each do | match |
|
17
|
+
resources[match[0]] = match[1]
|
18
|
+
end
|
19
|
+
return resources
|
15
20
|
end
|
21
|
+
|
22
|
+
def find_by_predicate_and_object(predicate, object)
|
23
|
+
if predicate.could_be_a_safe_curie?
|
24
|
+
predicate = Curie.parse predicate
|
25
|
+
end
|
26
|
+
if object.could_be_a_safe_curie?
|
27
|
+
object = Curie.parse object
|
28
|
+
end
|
29
|
+
object = self[object] if self[object]
|
30
|
+
matches = self.find_all {|r| [*r[1][predicate]].index(object) }
|
31
|
+
|
32
|
+
resources = Collection.new
|
33
|
+
matches.each do | match |
|
34
|
+
resources[match[0]] = match[1]
|
35
|
+
end
|
36
|
+
return resources
|
37
|
+
end
|
16
38
|
|
17
39
|
def find_or_create(uri)
|
18
40
|
if uri.could_be_a_safe_curie?
|
@@ -32,5 +54,36 @@ module RDFObject
|
|
32
54
|
parser.parse
|
33
55
|
nil
|
34
56
|
end
|
57
|
+
|
58
|
+
def to_ntriples
|
59
|
+
ntriples = ""
|
60
|
+
self.each_pair do | uri, resource |
|
61
|
+
ntriples << resource.to_ntriples
|
62
|
+
end
|
63
|
+
ntriples
|
64
|
+
end
|
65
|
+
|
66
|
+
def to_xml(depth=0)
|
67
|
+
namespaces = {}
|
68
|
+
rdf_data = ""
|
69
|
+
self.values.each do | resource |
|
70
|
+
ns, desc = resource.rdf_description_block(depth)
|
71
|
+
namespaces.merge!(ns)
|
72
|
+
rdf_data << desc
|
73
|
+
end
|
74
|
+
unless namespaces["xmlns:rdf"]
|
75
|
+
if x = namespaces.index("http://www.w3.org/1999/02/22-rdf-syntax-ns#")
|
76
|
+
namespaces.delete(x)
|
77
|
+
end
|
78
|
+
namespaces["xmlns:rdf"] = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
79
|
+
end
|
80
|
+
|
81
|
+
rdf = "<rdf:RDF"
|
82
|
+
namespaces.each_pair {|key, value| rdf << " #{key}=\"#{value}\""}
|
83
|
+
rdf <<">"
|
84
|
+
rdf << rdf_data
|
85
|
+
rdf << "</rdf:RDF>"
|
86
|
+
rdf
|
87
|
+
end
|
35
88
|
end
|
36
89
|
end
|
@@ -4,6 +4,7 @@ require 'curies'
|
|
4
4
|
|
5
5
|
module RDFObject
|
6
6
|
class Resource < OpenStruct
|
7
|
+
attr_reader :table
|
7
8
|
def initialize(uri)
|
8
9
|
if uri.could_be_a_safe_curie?
|
9
10
|
uri = Curie.parse uri
|
@@ -101,6 +102,123 @@ module RDFObject
|
|
101
102
|
end
|
102
103
|
return true
|
103
104
|
end
|
105
|
+
|
106
|
+
def to_ntriples
|
107
|
+
ntriples = ""
|
108
|
+
Curie.get_mappings.each do | prefix, uri |
|
109
|
+
if self[uri]
|
110
|
+
self[uri].keys.each do | pred |
|
111
|
+
if self[uri][pred].is_a?(Array)
|
112
|
+
objects = self[uri][pred]
|
113
|
+
else
|
114
|
+
objects = [self[uri][pred]]
|
115
|
+
end
|
116
|
+
objects.each do | object |
|
117
|
+
line = "<#{self.uri}> <#{uri}#{pred}> "
|
118
|
+
if (object.is_a?(Resource) or object.is_a?(ResourceReference))
|
119
|
+
line << "<#{object.uri}>"
|
120
|
+
else
|
121
|
+
line << "#{object.to_json}"
|
122
|
+
if (object.respond_to?(:data_type) || object.respond_to?(:language))
|
123
|
+
if object.data_type
|
124
|
+
line << "^^<#{object.data_type}>"
|
125
|
+
end
|
126
|
+
if object.language
|
127
|
+
line << "@#{object.language}"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
line << ".\n"
|
132
|
+
ntriples << line
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
ntriples
|
138
|
+
end
|
139
|
+
|
140
|
+
def to_xml(depth=0)
|
141
|
+
namespaces, rdf_data = rdf_description_block(depth)
|
142
|
+
unless namespaces["xmlns:rdf"]
|
143
|
+
if x = namespaces.index("http://www.w3.org/1999/02/22-rdf-syntax-ns#")
|
144
|
+
namespaces.delete(x)
|
145
|
+
end
|
146
|
+
namespaces["xmlns:rdf"] = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
147
|
+
end
|
148
|
+
|
149
|
+
rdf = "<rdf:RDF"
|
150
|
+
namespaces.each_pair {|key, value| rdf << " #{key}=\"#{value}\""}
|
151
|
+
rdf <<">"
|
152
|
+
rdf << rdf_data
|
153
|
+
rdf << "</rdf:RDF>"
|
154
|
+
rdf
|
155
|
+
end
|
156
|
+
|
157
|
+
def rdf_description_block(depth)
|
158
|
+
rdf = "<rdf:Description rdf:about=\"#{CGI.escapeHTML(self.uri)}\">"
|
159
|
+
namespaces = {}
|
160
|
+
Curie.get_mappings.each_pair do |key, value|
|
161
|
+
if self.respond_to?(key.to_sym)
|
162
|
+
self.send(key.to_sym).each_pair do | predicate, objects |
|
163
|
+
[*objects].each do | object |
|
164
|
+
rdf << "<#{key}:#{predicate}"
|
165
|
+
namespaces["xmlns:#{key}"] = "#{Curie.parse("[#{key}:]")}"
|
166
|
+
if object.is_a?(RDFObject::ResourceReference)
|
167
|
+
if depth > 0
|
168
|
+
rdf << " rdf:resource=\"#{CGI.escapeHTML(object.uri)}\" />"
|
169
|
+
else
|
170
|
+
rdf << ">"
|
171
|
+
ns, rdf_data = object.resource.rdf_description_block(depth+1)
|
172
|
+
namespaces.merge!(ns)
|
173
|
+
rdf << rdf_data
|
174
|
+
rdf << "</#{key}:#{predicate}>"
|
175
|
+
end
|
176
|
+
else
|
177
|
+
if object.language
|
178
|
+
rdf << " xml:lang=\"#{object.language}\""
|
179
|
+
end
|
180
|
+
if object.data_type
|
181
|
+
rdf << " rdf:datatype=\"#{object.data_type}\""
|
182
|
+
end
|
183
|
+
rdf << ">#{CGI.escapeHTML(object.to_s)}</#{key}:#{predicate}>"
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
rdf << "</rdf:Description>"
|
190
|
+
[namespaces, rdf]
|
191
|
+
end
|
192
|
+
|
193
|
+
def ==(other)
|
194
|
+
return false unless self.uri == other.uri
|
195
|
+
Curie.get_mappings.each do | prefix, uri |
|
196
|
+
next unless self[uri] or other[uri]
|
197
|
+
return false if self[uri] && !other[uri]
|
198
|
+
return false if !self[uri] && other[uri]
|
199
|
+
return false if self[uri].class != other[uri].class
|
200
|
+
if self[uri] != other[uri]
|
201
|
+
if self[uri].is_a?(Hash)
|
202
|
+
return false unless self[uri].keys.eql?(other[uri].keys)
|
203
|
+
self[uri].keys.each do | pred |
|
204
|
+
if self[uri][pred].is_a?(Array)
|
205
|
+
return false unless self[uri][pred].length == other[uri][pred].length
|
206
|
+
else
|
207
|
+
if self[uri][pred].is_a?(Resource) or self[uri][pred].is_a?(ResourceReference)
|
208
|
+
return false unless other[uri][pred].is_a?(Resource) or other[uri][pred].is_a?(ResourceReference)
|
209
|
+
return false unless self.uri == other.uri
|
210
|
+
else
|
211
|
+
return false unless self[uri][pred] == other[uri][pred]
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
else
|
216
|
+
return false
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
true
|
221
|
+
end
|
104
222
|
end
|
105
223
|
|
106
224
|
class ResourceReference
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rdfobjects
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ross Singer
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-10
|
12
|
+
date: 2009-11-10 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|