json-ld 1.0.1.1 → 1.0.3
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.
- checksums.yaml +14 -6
- data/README.md +2 -2
- data/VERSION +1 -1
- data/lib/json/ld/api.rb +8 -5
- data/lib/json/ld/compact.rb +2 -1
- data/lib/json/ld/context.rb +44 -33
- data/lib/json/ld/expand.rb +1 -1
- data/lib/json/ld/flatten.rb +9 -11
- data/lib/json/ld/from_rdf.rb +48 -45
- data/lib/json/ld/reader.rb +5 -0
- data/lib/json/ld/to_rdf.rb +5 -23
- data/lib/json/ld/utils.rb +9 -2
- data/spec/api_spec.rb +1 -1
- data/spec/compact_spec.rb +1 -2
- data/spec/flatten_spec.rb +3 -20
- data/spec/from_rdf_spec.rb +16 -29
- data/spec/matchers.rb +3 -3
- data/spec/reader_spec.rb +4 -4
- data/spec/suite_compact_spec.rb +0 -4
- data/spec/suite_to_rdf_spec.rb +2 -2
- data/spec/test-files/test-1-rdf.ttl +3 -3
- data/spec/test-files/test-3-rdf.ttl +1 -1
- data/spec/test-files/test-5-rdf.ttl +2 -2
- data/spec/test-files/test-6-rdf.ttl +2 -2
- data/spec/test-files/test-7-rdf.ttl +6 -6
- data/spec/to_rdf_spec.rb +32 -18
- data/spec/writer_spec.rb +0 -2
- metadata +33 -33
data/lib/json/ld/reader.rb
CHANGED
@@ -50,6 +50,11 @@ module JSON::LD
|
|
50
50
|
# @see RDF::Reader#each_statement
|
51
51
|
def each_statement(&block)
|
52
52
|
JSON::LD::API.toRDF(@doc, @options[:context], @options).each do |statement|
|
53
|
+
# If RDF version is 1.0, fold literals with xsd:string to be just simple literals
|
54
|
+
statement.object.datatype = nil if
|
55
|
+
RDF::VERSION.to_s < "1.1" &&
|
56
|
+
statement.object.literal? &&
|
57
|
+
statement.object.datatype == RDF::XSD.string
|
53
58
|
block.call(statement)
|
54
59
|
end
|
55
60
|
end
|
data/lib/json/ld/to_rdf.rb
CHANGED
@@ -20,7 +20,7 @@ module JSON::LD
|
|
20
20
|
# For each id-node in active_graph
|
21
21
|
active_graph.each do |id, node|
|
22
22
|
# Initialize subject as the IRI or BNode representation of id
|
23
|
-
subject = as_resource(id)
|
23
|
+
subject = as_resource(id, context.doc_base)
|
24
24
|
debug("graph_to_rdf") {"subject: #{subject.to_ntriples}"}
|
25
25
|
|
26
26
|
# For each property-values in node
|
@@ -29,7 +29,7 @@ module JSON::LD
|
|
29
29
|
when '@type'
|
30
30
|
# If property is @type, construct triple as an RDF Triple composed of id, rdf:type, and object from values where id and object are represented either as IRIs or Blank Nodes
|
31
31
|
results += values.map do |value|
|
32
|
-
object = as_resource(value)
|
32
|
+
object = as_resource(value, context.doc_base)
|
33
33
|
debug("graph_to_rdf") {"type: #{object.to_ntriples}"}
|
34
34
|
RDF::Statement.new(subject, RDF.type, object)
|
35
35
|
end
|
@@ -38,7 +38,7 @@ module JSON::LD
|
|
38
38
|
else
|
39
39
|
# Otherwise, property is an IRI or Blank Node identifier
|
40
40
|
# Initialize predicate from property as an IRI or Blank node
|
41
|
-
predicate = as_resource(property)
|
41
|
+
predicate = as_resource(property, context.doc_base)
|
42
42
|
debug("graph_to_rdf") {"predicate: #{predicate.to_ntriples}"}
|
43
43
|
|
44
44
|
# For each item in values
|
@@ -90,7 +90,7 @@ module JSON::LD
|
|
90
90
|
value = lit.to_s
|
91
91
|
datatype ||= lit.datatype
|
92
92
|
else
|
93
|
-
# Otherwise, if datatype is null, set it to xsd:string or
|
93
|
+
# Otherwise, if datatype is null, set it to xsd:string or xsd:langString, depending on if item has a @language key.
|
94
94
|
datatype ||= item.has_key?('@language') ? RDF.langString : RDF::XSD.string
|
95
95
|
end
|
96
96
|
|
@@ -104,7 +104,7 @@ module JSON::LD
|
|
104
104
|
# Otherwise, value must be a node definition containing only @id whos value is an IRI or Blank Node identifier
|
105
105
|
raise "Expected node reference, got #{item.inspect}" unless item.keys == %w(@id)
|
106
106
|
# Return value associated with @id as an IRI or Blank node
|
107
|
-
as_resource(item['@id'])
|
107
|
+
as_resource(item['@id'], context.doc_base)
|
108
108
|
end
|
109
109
|
end
|
110
110
|
|
@@ -145,23 +145,5 @@ module JSON::LD
|
|
145
145
|
def node
|
146
146
|
RDF::Node.new(namer.get_sym)
|
147
147
|
end
|
148
|
-
|
149
|
-
##
|
150
|
-
# add a statement, object can be literal or URI or bnode
|
151
|
-
#
|
152
|
-
# @param [String] path
|
153
|
-
# @param [RDF::Resource] subject the subject of the statement
|
154
|
-
# @param [RDF::URI] predicate the predicate of the statement
|
155
|
-
# @param [RDF::Term] object the object of the statement
|
156
|
-
# @param [RDF::Resource] name the named graph context of the statement
|
157
|
-
# @yield statement
|
158
|
-
# @yieldparam [RDF::Statement] statement
|
159
|
-
def add_quad(path, subject, predicate, object, name)
|
160
|
-
predicate = RDF.type if predicate == '@type'
|
161
|
-
object = context.expand_iri(object.to_s, :quiet => true) if object.literal? && predicate == RDF.type
|
162
|
-
statement = RDF::Statement.new(subject, predicate, object, :context => name)
|
163
|
-
debug(path) {"statement: #{statement.to_nquads}"}
|
164
|
-
yield statement
|
165
|
-
end
|
166
148
|
end
|
167
149
|
end
|
data/lib/json/ld/utils.rb
CHANGED
@@ -65,10 +65,17 @@ module JSON::LD
|
|
65
65
|
##
|
66
66
|
# Represent an id as an IRI or Blank Node
|
67
67
|
# @param [String] id
|
68
|
+
# @param [RDF::URI] base (nil)
|
68
69
|
# @return [RDF::Resource]
|
69
|
-
def as_resource(id)
|
70
|
+
def as_resource(id, base = nil)
|
70
71
|
@nodes ||= {} # Re-use BNodes
|
71
|
-
id[0,2] == '_:'
|
72
|
+
if id[0,2] == '_:'
|
73
|
+
(@nodes[id] ||= RDF::Node.new(id[2..-1]))
|
74
|
+
elsif base
|
75
|
+
base.join(id)
|
76
|
+
else
|
77
|
+
RDF::URI(id)
|
78
|
+
end
|
72
79
|
end
|
73
80
|
|
74
81
|
private
|
data/spec/api_spec.rb
CHANGED
@@ -33,7 +33,7 @@ describe JSON::LD::API do
|
|
33
33
|
end if File.exist?(framed) && File.exist?(frame)
|
34
34
|
|
35
35
|
it "toRDF" do
|
36
|
-
RDF::
|
36
|
+
RDF::Repository.load(filename, :debug => @debug).should be_equivalent_graph(RDF::Repository.load(ttl), :trace => @debug)
|
37
37
|
end if File.exist?(ttl)
|
38
38
|
end
|
39
39
|
end
|
data/spec/compact_spec.rb
CHANGED
@@ -336,8 +336,7 @@ describe JSON::LD::API do
|
|
336
336
|
"@context": {
|
337
337
|
"name": "http://xmlns.com/foaf/0.1/name",
|
338
338
|
"isKnownBy": {
|
339
|
-
"@reverse": "http://xmlns.com/foaf/0.1/knows"
|
340
|
-
"@type": "@id"
|
339
|
+
"@reverse": "http://xmlns.com/foaf/0.1/knows"
|
341
340
|
}
|
342
341
|
},
|
343
342
|
"@id": "http://example.com/people/markus",
|
data/spec/flatten_spec.rb
CHANGED
@@ -10,8 +10,7 @@ describe JSON::LD::API do
|
|
10
10
|
"single object" => {
|
11
11
|
:input => {"@id" => "http://example.com", "@type" => RDF::RDFS.Resource.to_s},
|
12
12
|
:output => [
|
13
|
-
{"@id" => "http://example.com", "@type" => [RDF::RDFS.Resource.to_s]}
|
14
|
-
{"@id" => RDF::RDFS.Resource.to_s}
|
13
|
+
{"@id" => "http://example.com", "@type" => [RDF::RDFS.Resource.to_s]}
|
15
14
|
]
|
16
15
|
},
|
17
16
|
"embedded object" => {
|
@@ -35,9 +34,7 @@ describe JSON::LD::API do
|
|
35
34
|
{
|
36
35
|
"@id" => "http://greggkellogg.net/foaf#me",
|
37
36
|
"@type" => [RDF::FOAF.Person.to_s]
|
38
|
-
}
|
39
|
-
{"@id" => RDF::FOAF.Person.to_s},
|
40
|
-
{"@id" => RDF::FOAF.PersonalProfile.to_s},
|
37
|
+
}
|
41
38
|
]
|
42
39
|
},
|
43
40
|
"embedded anon" => {
|
@@ -60,9 +57,7 @@ describe JSON::LD::API do
|
|
60
57
|
"@id" => "http://greggkellogg.net/foaf",
|
61
58
|
"@type" => [RDF::FOAF.PersonalProfile.to_s],
|
62
59
|
RDF::FOAF.primaryTopic.to_s => [{"@id" => "_:b0"}]
|
63
|
-
}
|
64
|
-
{"@id" => RDF::FOAF.Person.to_s},
|
65
|
-
{"@id" => RDF::FOAF.PersonalProfile.to_s},
|
60
|
+
}
|
66
61
|
]
|
67
62
|
},
|
68
63
|
"reverse properties" => {
|
@@ -149,8 +144,6 @@ describe JSON::LD::API do
|
|
149
144
|
{"@id": "http://www.brockhaus.de/"}
|
150
145
|
],
|
151
146
|
"@graph": [{
|
152
|
-
"@id": "http://example.org/location/France#this"
|
153
|
-
}, {
|
154
147
|
"@id": "http://example.org/location/Paris#this",
|
155
148
|
"http://example.org/locatedIn": [{"@id": "http://example.org/location/France#this"}]
|
156
149
|
}]
|
@@ -162,14 +155,6 @@ describe JSON::LD::API do
|
|
162
155
|
"@id": "http://example.org/location/Paris#this",
|
163
156
|
"http://example.org/hasPopulation": [{"@value": 7000000}]
|
164
157
|
}]
|
165
|
-
}, {
|
166
|
-
"@id": "http://www.britannica.com/"
|
167
|
-
}, {
|
168
|
-
"@id": "http://www.brockhaus.de/"
|
169
|
-
}, {
|
170
|
-
"@id": "http://www.w3.org/1999/02/22-rdf-syntax-ns#Graph"
|
171
|
-
}, {
|
172
|
-
"@id": "http://www.wikipedia.org/"
|
173
158
|
}])),
|
174
159
|
},
|
175
160
|
"Test Manifest (shortened)" => {
|
@@ -193,8 +178,6 @@ describe JSON::LD::API do
|
|
193
178
|
"@id": "#t0001",
|
194
179
|
"http://example/input": [{"@id": "error-expand-0001-in.jsonld"}],
|
195
180
|
"http://example/name": [{"@value": "Keywords cannot be aliased to other keywords"}]
|
196
|
-
}, {
|
197
|
-
"@id": "error-expand-0001-in.jsonld"
|
198
181
|
}]
|
199
182
|
}),
|
200
183
|
:options => {}
|
data/spec/from_rdf_spec.rb
CHANGED
@@ -12,9 +12,7 @@ describe JSON::LD::API do
|
|
12
12
|
{
|
13
13
|
'@id' => "http://a/b",
|
14
14
|
"http://a/c" => [{"@id" => "http://a/d"}]
|
15
|
-
|
16
|
-
'@id' => 'http://a/d'
|
17
|
-
}
|
15
|
+
}
|
18
16
|
], @debug)
|
19
17
|
end
|
20
18
|
|
@@ -27,9 +25,7 @@ describe JSON::LD::API do
|
|
27
25
|
{"@id" => "http://example.com/d"},
|
28
26
|
{"@id" => "http://example.com/e"}
|
29
27
|
]
|
30
|
-
}
|
31
|
-
{"@id" => "http://example.com/d"},
|
32
|
-
{"@id" => "http://example.com/e"}
|
28
|
+
}
|
33
29
|
], @debug)
|
34
30
|
end
|
35
31
|
|
@@ -40,9 +36,7 @@ describe JSON::LD::API do
|
|
40
36
|
'@id' => "http://example.com/b",
|
41
37
|
"http://example.com/c" => [{"@id" => "http://example.com/d"}],
|
42
38
|
"http://example.com/e" => [{"@id" => "http://example.com/f"}]
|
43
|
-
}
|
44
|
-
{"@id" => "http://example.com/d"},
|
45
|
-
{"@id" => "http://example.com/f"}
|
39
|
+
}
|
46
40
|
], @debug)
|
47
41
|
end
|
48
42
|
|
@@ -55,7 +49,6 @@ describe JSON::LD::API do
|
|
55
49
|
)
|
56
50
|
serialize(input).
|
57
51
|
should produce([
|
58
|
-
{'@id' => "http://www.w3.org/2006/03/test-description#TestCase"},
|
59
52
|
{'@id' => "test-cases/0001", '@type' => ["http://www.w3.org/2006/03/test-description#TestCase"]},
|
60
53
|
{'@id' => "test-cases/0002", '@type' => ["http://www.w3.org/2006/03/test-description#TestCase"]},
|
61
54
|
], @debug)
|
@@ -170,8 +163,7 @@ describe JSON::LD::API do
|
|
170
163
|
{
|
171
164
|
"@id" => "_:a",
|
172
165
|
"http://example.com/a" => [{"@id" => "http://example.com/b"}]
|
173
|
-
}
|
174
|
-
{"@id" => "http://example.com/b"}
|
166
|
+
}
|
175
167
|
], @debug)
|
176
168
|
end
|
177
169
|
|
@@ -185,8 +177,7 @@ describe JSON::LD::API do
|
|
185
177
|
{
|
186
178
|
"@id" => "http://example.com/a",
|
187
179
|
"http://example.com/b" => [{"@id" => "_:a"}]
|
188
|
-
}
|
189
|
-
{"@id" => "http://example.com/d"},
|
180
|
+
}
|
190
181
|
], @debug)
|
191
182
|
end
|
192
183
|
end
|
@@ -218,7 +209,7 @@ describe JSON::LD::API do
|
|
218
209
|
{"@id" => "http://example.com/c"}
|
219
210
|
]
|
220
211
|
}]
|
221
|
-
}
|
212
|
+
}], @debug)
|
222
213
|
end
|
223
214
|
|
224
215
|
it "should generate empty list" do
|
@@ -265,7 +256,7 @@ describe JSON::LD::API do
|
|
265
256
|
"@graph" => [{
|
266
257
|
"@id" => "http://example.com/a",
|
267
258
|
"http://example.com/b" => [{"@id" => "http://example.com/c"}]
|
268
|
-
}
|
259
|
+
}]
|
269
260
|
},
|
270
261
|
]
|
271
262
|
},
|
@@ -280,10 +271,9 @@ describe JSON::LD::API do
|
|
280
271
|
"@graph" => [{
|
281
272
|
"@id" => "http://example.com/a",
|
282
273
|
"http://example.com/b" => [{"@id" => "http://example.com/c"}]
|
283
|
-
}
|
274
|
+
}],
|
284
275
|
"http://example.com/d" => [{"@id" => "http://example.com/e"}]
|
285
|
-
}
|
286
|
-
{"@id" => "http://example.com/e"}
|
276
|
+
}
|
287
277
|
]
|
288
278
|
},
|
289
279
|
"with lists" => {
|
@@ -301,10 +291,9 @@ describe JSON::LD::API do
|
|
301
291
|
"@graph" => [{
|
302
292
|
"@id" => "http://example.com/a",
|
303
293
|
"http://example.com/b" => [{"@list" => [{"@id" => "http://example.com/c"}]}]
|
304
|
-
}
|
294
|
+
}],
|
305
295
|
"http://example.com/d" => [{"@list" => [{"@id" => "http://example.com/e"}]}]
|
306
|
-
}
|
307
|
-
{"@id" => "http://example.com/e"}
|
296
|
+
}
|
308
297
|
]
|
309
298
|
},
|
310
299
|
"Two Graphs with same subject and lists" => {
|
@@ -325,8 +314,7 @@ describe JSON::LD::API do
|
|
325
314
|
"http://example.com/b" => [{
|
326
315
|
"@list" => [{"@id" => "http://example.com/c"}]
|
327
316
|
}]
|
328
|
-
}
|
329
|
-
{"@id" => "http://example.com/c"}
|
317
|
+
}
|
330
318
|
]
|
331
319
|
},
|
332
320
|
{
|
@@ -337,8 +325,7 @@ describe JSON::LD::API do
|
|
337
325
|
"http://example.com/b" => [{
|
338
326
|
"@list" => [{"@id" => "http://example.com/e"}]
|
339
327
|
}]
|
340
|
-
}
|
341
|
-
{"@id" => "http://example.com/e"}
|
328
|
+
}
|
342
329
|
]
|
343
330
|
}
|
344
331
|
]
|
@@ -357,7 +344,7 @@ describe JSON::LD::API do
|
|
357
344
|
serialize(input, :useRdfType => false).should produce([{
|
358
345
|
'@id' => "http://example.com/a",
|
359
346
|
"@type" => ["http://example.com/b"]
|
360
|
-
}
|
347
|
+
}], @debug)
|
361
348
|
end
|
362
349
|
|
363
350
|
it "does not use @type if set to true" do
|
@@ -365,7 +352,7 @@ describe JSON::LD::API do
|
|
365
352
|
serialize(input, :useRdfType => true).should produce([{
|
366
353
|
'@id' => "http://example.com/a",
|
367
354
|
'@type' => ["http://example.com/b"]
|
368
|
-
}
|
355
|
+
}], @debug)
|
369
356
|
end
|
370
357
|
end
|
371
358
|
|
@@ -383,7 +370,7 @@ describe JSON::LD::API do
|
|
383
370
|
"http://www.w3.org/2000/01/rdf-schema#range" => [
|
384
371
|
{ "@id" => "http://www.w3.org/2001/XMLSchema#boolean" }
|
385
372
|
]
|
386
|
-
}
|
373
|
+
}]
|
387
374
|
],
|
388
375
|
}.each do |t, (input, output)|
|
389
376
|
it "#{t}" do
|
data/spec/matchers.rb
CHANGED
@@ -6,12 +6,12 @@ Info = Struct.new(:about, :information, :trace, :inputDocument, :outputDocument,
|
|
6
6
|
|
7
7
|
def normalize(graph)
|
8
8
|
case graph
|
9
|
-
when RDF::
|
9
|
+
when RDF::Enumerable then graph
|
10
10
|
when IO, StringIO
|
11
11
|
RDF::Graph.new.load(graph, :base => @info.about)
|
12
12
|
else
|
13
13
|
# Figure out which parser to use
|
14
|
-
g = RDF::
|
14
|
+
g = RDF::Repository.new
|
15
15
|
reader_class = detect_format(graph)
|
16
16
|
reader_class.new(graph, :base => @info.about).each {|s| g << s}
|
17
17
|
g
|
@@ -37,7 +37,7 @@ RSpec::Matchers.define :be_equivalent_graph do |expected, info|
|
|
37
37
|
|
38
38
|
failure_message_for_should do |actual|
|
39
39
|
info = @info.respond_to?(:information) ? @info.information : @info.inspect
|
40
|
-
if @expected.is_a?(RDF::
|
40
|
+
if @expected.is_a?(RDF::Enumerable) && @actual.size != @expected.size
|
41
41
|
"Graph entry count differs:\nexpected: #{@expected.size}\nactual: #{@actual.size}"
|
42
42
|
elsif @expected.is_a?(Array) && @actual.size != @expected.length
|
43
43
|
"Graph entry count differs:\nexpected: #{@expected.length}\nactual: #{@actual.size}"
|
data/spec/reader_spec.rb
CHANGED
@@ -36,7 +36,7 @@ describe JSON::LD::Reader do
|
|
36
36
|
|
37
37
|
describe "#initialize" do
|
38
38
|
it "yields reader given string" do
|
39
|
-
inner =
|
39
|
+
inner = double("inner")
|
40
40
|
inner.should_receive(:called).with(JSON::LD::Reader)
|
41
41
|
JSON::LD::Reader.new(subject) do |reader|
|
42
42
|
inner.called(reader.class)
|
@@ -44,7 +44,7 @@ describe JSON::LD::Reader do
|
|
44
44
|
end
|
45
45
|
|
46
46
|
it "yields reader given IO" do
|
47
|
-
inner =
|
47
|
+
inner = double("inner")
|
48
48
|
inner.should_receive(:called).with(JSON::LD::Reader)
|
49
49
|
JSON::LD::Reader.new(StringIO.new(subject)) do |reader|
|
50
50
|
inner.called(reader.class)
|
@@ -58,7 +58,7 @@ describe JSON::LD::Reader do
|
|
58
58
|
|
59
59
|
describe "#each_statement" do
|
60
60
|
it "yields statements" do
|
61
|
-
inner =
|
61
|
+
inner = double("inner")
|
62
62
|
inner.should_receive(:called).with(RDF::Statement).exactly(3)
|
63
63
|
JSON::LD::Reader.new(subject).each_statement do |statement|
|
64
64
|
inner.called(statement.class)
|
@@ -68,7 +68,7 @@ describe JSON::LD::Reader do
|
|
68
68
|
|
69
69
|
describe "#each_triple" do
|
70
70
|
it "yields statements" do
|
71
|
-
inner =
|
71
|
+
inner = double("inner")
|
72
72
|
inner.should_receive(:called).exactly(3)
|
73
73
|
JSON::LD::Reader.new(subject).each_triple do |subject, predicate, object|
|
74
74
|
inner.called(subject.class, predicate.class, object.class)
|
data/spec/suite_compact_spec.rb
CHANGED
@@ -10,10 +10,6 @@ describe JSON::LD do
|
|
10
10
|
m.entries.each do |t|
|
11
11
|
specify "#{t.property('input')}: #{t.name}" do
|
12
12
|
begin
|
13
|
-
#case t.property('input')
|
14
|
-
#when /compact-(0032|0033|0034)/
|
15
|
-
# pending("undesireable property generator corner cases")
|
16
|
-
#end
|
17
13
|
t.debug = ["test: #{t.inspect}", "source: #{t.input.read}"]
|
18
14
|
if t.property('context')
|
19
15
|
t.debug << "context: #{t.context.read}"
|
data/spec/suite_to_rdf_spec.rb
CHANGED
@@ -18,8 +18,8 @@ describe JSON::LD do
|
|
18
18
|
to_quad(statement)
|
19
19
|
end
|
20
20
|
|
21
|
-
sorted_expected = t.expect.readlines.sort.join("")
|
22
|
-
quads.sort.join("").should produce(sorted_expected, t.debug)
|
21
|
+
sorted_expected = t.expect.readlines.uniq.sort.join("")
|
22
|
+
quads.uniq.sort.join("").should produce(sorted_expected, t.debug)
|
23
23
|
rescue JSON::LD::ProcessingError => e
|
24
24
|
fail("Processing error: #{e.message}")
|
25
25
|
rescue JSON::LD::InvalidContext => e
|
@@ -3,6 +3,6 @@
|
|
3
3
|
@prefix name: <http://xmlns.com/foaf/0.1/name> .
|
4
4
|
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
5
5
|
|
6
|
-
[ avatar: "http://twitter.com/account/profile_image/manusporny"
|
7
|
-
homepage: "http://manu.sporny.org/"
|
8
|
-
name: "Manu Sporny"
|
6
|
+
[ avatar: "http://twitter.com/account/profile_image/manusporny";
|
7
|
+
homepage: "http://manu.sporny.org/";
|
8
|
+
name: "Manu Sporny"] .
|
@@ -2,5 +2,5 @@
|
|
2
2
|
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
3
3
|
|
4
4
|
<http://example.org/people#joebob> a foaf:Person;
|
5
|
-
foaf:name "Joe Bob"
|
6
|
-
foaf:nick ("joe"
|
5
|
+
foaf:name "Joe Bob";
|
6
|
+
foaf:nick ("joe" "bob" "jaybe") .
|