json-ld 3.2.4 → 3.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +4 -4
- data/VERSION +1 -1
- data/lib/json/ld/api.rb +807 -771
- data/lib/json/ld/compact.rb +304 -304
- data/lib/json/ld/conneg.rb +179 -161
- data/lib/json/ld/context.rb +2079 -1913
- data/lib/json/ld/expand.rb +745 -666
- data/lib/json/ld/extensions.rb +14 -13
- data/lib/json/ld/flatten.rb +257 -247
- data/lib/json/ld/format.rb +202 -194
- data/lib/json/ld/frame.rb +525 -502
- data/lib/json/ld/from_rdf.rb +223 -204
- data/lib/json/ld/html/nokogiri.rb +123 -121
- data/lib/json/ld/html/rexml.rb +151 -147
- data/lib/json/ld/reader.rb +107 -100
- data/lib/json/ld/resource.rb +224 -205
- data/lib/json/ld/streaming_reader.rb +574 -507
- data/lib/json/ld/streaming_writer.rb +93 -92
- data/lib/json/ld/to_rdf.rb +171 -169
- data/lib/json/ld/utils.rb +270 -264
- data/lib/json/ld/version.rb +24 -14
- data/lib/json/ld/writer.rb +334 -311
- data/lib/json/ld.rb +103 -96
- metadata +56 -225
- data/spec/api_spec.rb +0 -132
- data/spec/compact_spec.rb +0 -3482
- data/spec/conneg_spec.rb +0 -373
- data/spec/context_spec.rb +0 -2056
- data/spec/expand_spec.rb +0 -4496
- data/spec/flatten_spec.rb +0 -1203
- data/spec/format_spec.rb +0 -115
- data/spec/frame_spec.rb +0 -2541
- data/spec/from_rdf_spec.rb +0 -1072
- data/spec/matchers.rb +0 -20
- data/spec/rdfstar_spec.rb +0 -25
- data/spec/reader_spec.rb +0 -883
- data/spec/resource_spec.rb +0 -76
- data/spec/spec_helper.rb +0 -281
- data/spec/streaming_reader_spec.rb +0 -237
- data/spec/streaming_writer_spec.rb +0 -145
- data/spec/suite_compact_spec.rb +0 -22
- data/spec/suite_expand_spec.rb +0 -36
- data/spec/suite_flatten_spec.rb +0 -34
- data/spec/suite_frame_spec.rb +0 -29
- data/spec/suite_from_rdf_spec.rb +0 -22
- data/spec/suite_helper.rb +0 -411
- data/spec/suite_html_spec.rb +0 -22
- data/spec/suite_http_spec.rb +0 -35
- data/spec/suite_remote_doc_spec.rb +0 -22
- data/spec/suite_to_rdf_spec.rb +0 -30
- data/spec/support/extensions.rb +0 -44
- data/spec/test-files/test-1-compacted.jsonld +0 -10
- data/spec/test-files/test-1-context.jsonld +0 -7
- data/spec/test-files/test-1-expanded.jsonld +0 -5
- data/spec/test-files/test-1-input.jsonld +0 -10
- data/spec/test-files/test-1-rdf.ttl +0 -8
- data/spec/test-files/test-2-compacted.jsonld +0 -20
- data/spec/test-files/test-2-context.jsonld +0 -7
- data/spec/test-files/test-2-expanded.jsonld +0 -16
- data/spec/test-files/test-2-input.jsonld +0 -20
- data/spec/test-files/test-2-rdf.ttl +0 -14
- data/spec/test-files/test-3-compacted.jsonld +0 -11
- data/spec/test-files/test-3-context.jsonld +0 -8
- data/spec/test-files/test-3-expanded.jsonld +0 -10
- data/spec/test-files/test-3-input.jsonld +0 -11
- data/spec/test-files/test-3-rdf.ttl +0 -8
- data/spec/test-files/test-4-compacted.jsonld +0 -10
- data/spec/test-files/test-4-context.jsonld +0 -7
- data/spec/test-files/test-4-expanded.jsonld +0 -6
- data/spec/test-files/test-4-input.jsonld +0 -10
- data/spec/test-files/test-4-rdf.ttl +0 -5
- data/spec/test-files/test-5-compacted.jsonld +0 -13
- data/spec/test-files/test-5-context.jsonld +0 -7
- data/spec/test-files/test-5-expanded.jsonld +0 -9
- data/spec/test-files/test-5-input.jsonld +0 -13
- data/spec/test-files/test-5-rdf.ttl +0 -7
- data/spec/test-files/test-6-compacted.jsonld +0 -10
- data/spec/test-files/test-6-context.jsonld +0 -7
- data/spec/test-files/test-6-expanded.jsonld +0 -10
- data/spec/test-files/test-6-input.jsonld +0 -10
- data/spec/test-files/test-6-rdf.ttl +0 -6
- data/spec/test-files/test-7-compacted.jsonld +0 -23
- data/spec/test-files/test-7-context.jsonld +0 -4
- data/spec/test-files/test-7-expanded.jsonld +0 -20
- data/spec/test-files/test-7-input.jsonld +0 -23
- data/spec/test-files/test-7-rdf.ttl +0 -14
- data/spec/test-files/test-8-compacted.jsonld +0 -34
- data/spec/test-files/test-8-context.jsonld +0 -11
- data/spec/test-files/test-8-expanded.jsonld +0 -24
- data/spec/test-files/test-8-frame.jsonld +0 -18
- data/spec/test-files/test-8-framed.jsonld +0 -25
- data/spec/test-files/test-8-input.jsonld +0 -30
- data/spec/test-files/test-8-rdf.ttl +0 -15
- data/spec/test-files/test-9-compacted.jsonld +0 -20
- data/spec/test-files/test-9-context.jsonld +0 -13
- data/spec/test-files/test-9-expanded.jsonld +0 -14
- data/spec/test-files/test-9-input.jsonld +0 -12
- data/spec/to_rdf_spec.rb +0 -1684
- data/spec/writer_spec.rb +0 -427
@@ -1,116 +1,117 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
1
|
# frozen_string_literal: true
|
3
|
-
module JSON::LD
|
4
|
-
##
|
5
|
-
# Streaming writer interface.
|
6
|
-
#
|
7
|
-
# Writes an array of statements serialized in expanded JSON-LD. No provision for turning rdf:first/rest into @list encodings.
|
8
|
-
# @author [Gregg Kellogg](http://greggkellogg.net/)
|
9
|
-
module StreamingWriter
|
10
|
-
##
|
11
|
-
# Write out array start, and note not to prepend node-separating ','
|
12
|
-
# @return [void] `self`
|
13
|
-
def stream_prologue
|
14
|
-
|
15
|
-
# If we were provided a context, or prefixes, use them to compact the output
|
16
|
-
@context = case @options[:context]
|
17
|
-
when nil then nil
|
18
|
-
when Context then @options[:context]
|
19
|
-
else Context.parse(@options[:context])
|
20
|
-
end
|
21
|
-
|
22
|
-
# log_debug("prologue") {"context: #{context.inspect}"}
|
23
|
-
if context
|
24
|
-
@output.puts %({"@context": #{context.serialize['@context'].to_json}, "@graph": [)
|
25
|
-
else
|
26
|
-
@output.puts "["
|
27
|
-
end
|
28
|
-
self
|
29
|
-
end
|
30
2
|
|
3
|
+
module JSON
|
4
|
+
module LD
|
31
5
|
##
|
32
|
-
#
|
33
|
-
#
|
34
|
-
# Once a new/first statement is seen, terminate the current node definition and compact if provided a context.
|
35
|
-
#
|
36
|
-
# Also expects all statements in the same context to be contained in a block including all subjects in a block (except for list elements)
|
6
|
+
# Streaming writer interface.
|
37
7
|
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
|
41
|
-
|
42
|
-
#
|
43
|
-
|
44
|
-
|
45
|
-
|
8
|
+
# Writes an array of statements serialized in expanded JSON-LD. No provision for turning rdf:first/rest into @list encodings.
|
9
|
+
# @author [Gregg Kellogg](http://greggkellogg.net/)
|
10
|
+
module StreamingWriter
|
11
|
+
##
|
12
|
+
# Write out array start, and note not to prepend node-separating ','
|
13
|
+
# @return [void] `self`
|
14
|
+
def stream_prologue
|
15
|
+
# If we were provided a context, or prefixes, use them to compact the output
|
16
|
+
@context = case @options[:context]
|
17
|
+
when nil then nil
|
18
|
+
when Context then @options[:context]
|
19
|
+
else Context.parse(@options[:context])
|
20
|
+
end
|
21
|
+
|
22
|
+
# log_debug("prologue") {"context: #{context.inspect}"}
|
23
|
+
if context
|
24
|
+
@output.puts %({"@context": #{context.serialize['@context'].to_json}, "@graph": [)
|
25
|
+
else
|
26
|
+
@output.puts "["
|
27
|
+
end
|
28
|
+
self
|
46
29
|
end
|
47
30
|
|
48
|
-
|
49
|
-
|
31
|
+
##
|
32
|
+
# Write a statement, creating a current node definition, if necessary.
|
33
|
+
#
|
34
|
+
# Once a new/first statement is seen, terminate the current node definition and compact if provided a context.
|
35
|
+
#
|
36
|
+
# Also expects all statements in the same context to be contained in a block including all subjects in a block (except for list elements)
|
37
|
+
#
|
38
|
+
# Note that if list elements are not received in order using the same subject and property, this may cause a bad serialization.
|
39
|
+
#
|
40
|
+
# @return [void] `self`
|
41
|
+
def stream_statement(statement)
|
42
|
+
# log_debug("ss") {"state: #{@state.inspect}, stmt: #{statement}"}
|
43
|
+
if @current_graph != statement.graph_name
|
44
|
+
end_graph
|
45
|
+
start_graph(statement.graph_name)
|
46
|
+
end
|
50
47
|
|
51
|
-
|
52
|
-
|
53
|
-
@current_node_def = {'@id' => statement.subject.to_s}
|
54
|
-
end
|
48
|
+
# If we're writing a list
|
49
|
+
@current_node_def ||= { '@id' => statement.subject.to_s }
|
55
50
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
51
|
+
if statement.subject.to_s != @current_node_def['@id']
|
52
|
+
end_node
|
53
|
+
@current_node_def = { '@id' => statement.subject.to_s }
|
54
|
+
end
|
60
55
|
|
61
|
-
|
62
|
-
|
63
|
-
elsif statement.object.datatype == RDF::URI(RDF.to_uri + "JSON")
|
64
|
-
{"@value" => MultiJson.load(statement.object.to_s), "@type" => "@json"}
|
56
|
+
if statement.predicate == RDF.type
|
57
|
+
(@current_node_def['@type'] ||= []) << statement.object.to_s
|
65
58
|
else
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
59
|
+
pd = (@current_node_def[statement.predicate.to_s] ||= [])
|
60
|
+
|
61
|
+
pd << if statement.object.resource?
|
62
|
+
{ '@id' => statement.object.to_s }
|
63
|
+
elsif statement.object.datatype == RDF_JSON
|
64
|
+
{ "@value" => MultiJson.load(statement.object.to_s), "@type" => "@json" }
|
65
|
+
else
|
66
|
+
lit = { "@value" => statement.object.to_s }
|
67
|
+
lit["@type"] = statement.object.datatype.to_s if statement.object.datatype?
|
68
|
+
lit["@language"] = statement.object.language.to_s if statement.object.language?
|
69
|
+
lit
|
70
|
+
end
|
70
71
|
end
|
72
|
+
self
|
71
73
|
end
|
72
|
-
self
|
73
|
-
end
|
74
74
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
75
|
+
##
|
76
|
+
# Complete open statements
|
77
|
+
# @return [void] `self`
|
78
|
+
def stream_epilogue
|
79
|
+
# log_debug("epilogue") {"state: #{@state.inspect}"}
|
80
|
+
end_graph
|
81
|
+
if context
|
82
|
+
@output.puts "\n]}"
|
83
|
+
else
|
84
|
+
@output.puts "\n]"
|
85
|
+
end
|
86
|
+
self
|
85
87
|
end
|
86
|
-
self
|
87
|
-
end
|
88
88
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
89
|
+
private
|
90
|
+
|
91
|
+
def start_graph(resource)
|
92
|
+
# log_debug("start_graph") {"state: #{@state.inspect}, resource: #{resource}"}
|
93
|
+
if resource
|
94
|
+
@output.puts(",") if %i[wrote_node wrote_graph].include?(@state)
|
95
|
+
@output.puts %({"@id": "#{resource}", "@graph": [)
|
96
|
+
@state = :in_graph
|
97
|
+
end
|
98
|
+
@current_graph = resource
|
97
99
|
end
|
98
|
-
@current_graph = resource
|
99
|
-
end
|
100
100
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
101
|
+
def end_graph
|
102
|
+
# log_debug("end_graph") {"state: #{@state.inspect}, ctx: #{@current_graph}"}
|
103
|
+
end_node
|
104
|
+
return unless @current_graph
|
105
|
+
|
105
106
|
@output.write %(]})
|
106
107
|
@state = :wrote_graph
|
107
108
|
end
|
108
|
-
end
|
109
109
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
110
|
+
def end_node
|
111
|
+
# log_debug("end_node") {"state: #{@state.inspect}, node: #{@current_node_def.to_json}"}
|
112
|
+
@output.puts(",") if %i[wrote_node wrote_graph].include?(@state)
|
113
|
+
return unless @current_node_def
|
114
|
+
|
114
115
|
node_def = if context
|
115
116
|
compacted = JSON::LD::API.compact(@current_node_def, context, rename_bnodes: false, **@options)
|
116
117
|
compacted.delete('@context')
|
data/lib/json/ld/to_rdf.rb
CHANGED
@@ -1,194 +1,196 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
1
|
# frozen_string_literal: true
|
2
|
+
|
3
3
|
require 'rdf'
|
4
4
|
require 'rdf/nquads'
|
5
5
|
require 'json/canonicalization'
|
6
6
|
|
7
|
-
module JSON
|
8
|
-
module
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
value
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
value.
|
38
|
-
|
39
|
-
|
40
|
-
as_double = value.ceil != value || value >= 1e21 || datatype == RDF::XSD.double
|
41
|
-
lit = if as_double
|
42
|
-
RDF::Literal::Double.new(value, canonicalize: true)
|
7
|
+
module JSON
|
8
|
+
module LD
|
9
|
+
module ToRDF
|
10
|
+
include Utils
|
11
|
+
|
12
|
+
##
|
13
|
+
# @param [Hash{String => Object}] item
|
14
|
+
# @param [RDF::Resource] graph_name
|
15
|
+
# @param [Boolean] quoted emitted triples are quoted triples.
|
16
|
+
# @yield statement
|
17
|
+
# @yieldparam [RDF::Statement] statement
|
18
|
+
# @return RDF::Resource the subject of this item
|
19
|
+
def item_to_rdf(item, graph_name: nil, quoted: false, &block)
|
20
|
+
# Just return value object as Term
|
21
|
+
return unless item
|
22
|
+
|
23
|
+
if value?(item)
|
24
|
+
value = item.fetch('@value')
|
25
|
+
datatype = item.fetch('@type', nil)
|
26
|
+
|
27
|
+
datatype = RDF_JSON if datatype == '@json'
|
28
|
+
|
29
|
+
case value
|
30
|
+
when RDF::Value
|
31
|
+
return value
|
32
|
+
when TrueClass, FalseClass
|
33
|
+
# If value is true or false, then set value its canonical lexical form as defined in the section Data Round Tripping. If datatype is null, set it to xsd:boolean.
|
34
|
+
value = value.to_s
|
35
|
+
datatype ||= RDF::XSD.boolean.to_s
|
36
|
+
when Numeric
|
37
|
+
# Otherwise, if value is a number, then set value to its canonical lexical form as defined in the section Data Round Tripping. If datatype is null, set it to either xsd:integer or xsd:double, depending on if the value contains a fractional and/or an exponential component.
|
38
|
+
value = if datatype == RDF_JSON
|
39
|
+
value.to_json_c14n
|
43
40
|
else
|
44
|
-
|
41
|
+
# Don't serialize as double if there are no fractional bits
|
42
|
+
as_double = value.ceil != value || value >= 1e21 || datatype == RDF::XSD.double
|
43
|
+
lit = if as_double
|
44
|
+
RDF::Literal::Double.new(value, canonicalize: true)
|
45
|
+
else
|
46
|
+
RDF::Literal.new(value.numerator, canonicalize: true)
|
47
|
+
end
|
48
|
+
|
49
|
+
datatype ||= lit.datatype
|
50
|
+
lit.to_s.sub("E+", "E")
|
45
51
|
end
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
yield RDF::Statement(cl, RDF.to_uri + 'direction', item['@direction'])
|
64
|
-
return cl
|
52
|
+
when Array, Hash
|
53
|
+
# Only valid for rdf:JSON
|
54
|
+
value = value.to_json_c14n
|
55
|
+
else
|
56
|
+
if item.key?('@direction') && @options[:rdfDirection]
|
57
|
+
# Either serialize using a datatype, or a compound-literal
|
58
|
+
case @options[:rdfDirection]
|
59
|
+
when 'i18n-datatype'
|
60
|
+
datatype = RDF::URI("https://www.w3.org/ns/i18n##{item.fetch('@language',
|
61
|
+
'').downcase}_#{item['@direction']}")
|
62
|
+
when 'compound-literal'
|
63
|
+
cl = RDF::Node.new
|
64
|
+
yield RDF::Statement(cl, RDF.value, item['@value'].to_s)
|
65
|
+
yield RDF::Statement(cl, RDF_LANGUAGE, item['@language'].downcase) if item['@language']
|
66
|
+
yield RDF::Statement(cl, RDF_DIRECTION, item['@direction'])
|
67
|
+
return cl
|
68
|
+
end
|
65
69
|
end
|
66
|
-
end
|
67
70
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
value = value.to_json_c14n
|
71
|
+
# Otherwise, if datatype is null, set it to xsd:string or xsd:langString, depending on if item has a @language key.
|
72
|
+
datatype ||= item.key?('@language') ? RDF.langString : RDF::XSD.string
|
73
|
+
value = value.to_json_c14n if datatype == RDF_JSON
|
72
74
|
end
|
75
|
+
datatype = RDF::URI(datatype) if datatype && !datatype.is_a?(RDF::URI)
|
76
|
+
|
77
|
+
# Initialize literal as an RDF literal using value and datatype. If element has the key @language and datatype is xsd:string, then add the value associated with the @language key as the language of the object.
|
78
|
+
language = item.fetch('@language', nil) if datatype == RDF.langString
|
79
|
+
return RDF::Literal.new(value, datatype: datatype, language: language)
|
80
|
+
elsif list?(item)
|
81
|
+
# If item is a list object, initialize list_results as an empty array, and object to the result of the List Conversion algorithm, passing the value associated with the @list key from item and list_results.
|
82
|
+
return parse_list(item['@list'], graph_name: graph_name, &block)
|
73
83
|
end
|
74
|
-
datatype = RDF::URI(datatype) if datatype && !datatype.is_a?(RDF::URI)
|
75
|
-
|
76
|
-
# Initialize literal as an RDF literal using value and datatype. If element has the key @language and datatype is xsd:string, then add the value associated with the @language key as the language of the object.
|
77
|
-
language = item.fetch('@language', nil) if datatype == RDF.langString
|
78
|
-
return RDF::Literal.new(value, datatype: datatype, language: language)
|
79
|
-
elsif list?(item)
|
80
|
-
# If item is a list object, initialize list_results as an empty array, and object to the result of the List Conversion algorithm, passing the value associated with the @list key from item and list_results.
|
81
|
-
return parse_list(item['@list'], graph_name: graph_name, &block)
|
82
|
-
end
|
83
84
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
85
|
+
subject = case item['@id']
|
86
|
+
when nil then node
|
87
|
+
when String then as_resource(item['@id'])
|
88
|
+
when Object
|
89
|
+
# Embedded/quoted statement
|
90
|
+
# (No error checking, as this is done in expansion)
|
91
|
+
to_enum(:item_to_rdf, item['@id'], quoted: true).to_a.first
|
92
|
+
end
|
92
93
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
end
|
103
|
-
when '@graph'
|
104
|
-
values = [values].compact unless values.is_a?(Array)
|
105
|
-
values.each do |nd|
|
106
|
-
item_to_rdf(nd, graph_name: subject, quoted: quoted, &block)
|
107
|
-
end
|
108
|
-
when '@reverse'
|
109
|
-
raise "Huh?" unless values.is_a?(Hash)
|
110
|
-
values.each do |prop, vv|
|
111
|
-
predicate = as_resource(prop)
|
112
|
-
# log_debug("item_to_rdf") {"@reverse predicate: #{predicate.to_ntriples rescue 'malformed rdf'}"}
|
113
|
-
# For each item in values
|
114
|
-
vv.each do |v|
|
115
|
-
# Item is a node definition. Generate object as the result of the Object Converstion algorithm passing item.
|
116
|
-
object = item_to_rdf(v, graph_name: graph_name, &block)
|
117
|
-
# log_debug("item_to_rdf") {"subject: #{object.to_ntriples rescue 'malformed rdf'}"}
|
118
|
-
# yield subject, prediate, and literal to results.
|
119
|
-
yield RDF::Statement(object, predicate, subject, graph_name: graph_name, quoted: quoted)
|
94
|
+
# log_debug("item_to_rdf") {"subject: #{subject.to_ntriples rescue 'malformed rdf'}"}
|
95
|
+
item.each do |property, values|
|
96
|
+
case property
|
97
|
+
when '@type'
|
98
|
+
# 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
|
99
|
+
values.each do |v|
|
100
|
+
object = as_resource(v)
|
101
|
+
# log_debug("item_to_rdf") {"type: #{object.to_ntriples rescue 'malformed rdf'}"}
|
102
|
+
yield RDF::Statement(subject, RDF.type, object, graph_name: graph_name, quoted: quoted)
|
120
103
|
end
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
104
|
+
when '@graph'
|
105
|
+
values = [values].compact unless values.is_a?(Array)
|
106
|
+
values.each do |nd|
|
107
|
+
item_to_rdf(nd, graph_name: subject, quoted: quoted, &block)
|
108
|
+
end
|
109
|
+
when '@reverse'
|
110
|
+
raise "Huh?" unless values.is_a?(Hash)
|
111
|
+
|
112
|
+
values.each do |prop, vv|
|
113
|
+
predicate = as_resource(prop)
|
114
|
+
# log_debug("item_to_rdf") {"@reverse predicate: #{predicate.to_ntriples rescue 'malformed rdf'}"}
|
115
|
+
# For each item in values
|
116
|
+
vv.each do |v|
|
117
|
+
# Item is a node definition. Generate object as the result of the Object Converstion algorithm passing item.
|
118
|
+
object = item_to_rdf(v, graph_name: graph_name, &block)
|
119
|
+
# log_debug("item_to_rdf") {"subject: #{object.to_ntriples rescue 'malformed rdf'}"}
|
120
|
+
# yield subject, prediate, and literal to results.
|
121
|
+
yield RDF::Statement(object, predicate, subject, graph_name: graph_name, quoted: quoted)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
when '@included'
|
125
|
+
values.each do |v|
|
126
|
+
item_to_rdf(v, graph_name: graph_name, &block)
|
127
|
+
end
|
128
|
+
when /^@/
|
129
|
+
# Otherwise, if @type is any other keyword, skip to the next property-values pair
|
130
|
+
else
|
131
|
+
# Otherwise, property is an IRI or Blank Node identifier
|
132
|
+
# Initialize predicate from property as an IRI or Blank node
|
133
|
+
predicate = as_resource(property)
|
134
|
+
# log_debug("item_to_rdf") {"predicate: #{predicate.to_ntriples rescue 'malformed rdf'}"}
|
135
|
+
|
136
|
+
# For each item in values
|
137
|
+
values.each do |v|
|
138
|
+
if list?(v)
|
139
|
+
# log_debug("item_to_rdf") {"list: #{v.inspect}"}
|
140
|
+
# If item is a list object, initialize list_results as an empty array, and object to the result of the List Conversion algorithm, passing the value associated with the @list key from item and list_results.
|
141
|
+
object = parse_list(v['@list'], graph_name: graph_name, &block)
|
142
|
+
|
143
|
+
# Append a triple composed of subject, prediate, and object to results and add all triples from list_results to results.
|
144
|
+
else
|
145
|
+
# Otherwise, item is a value object or a node definition. Generate object as the result of the Object Converstion algorithm passing item.
|
146
|
+
object = item_to_rdf(v, graph_name: graph_name, &block)
|
147
|
+
# log_debug("item_to_rdf") {"object: #{object.to_ntriples rescue 'malformed rdf'}"}
|
148
|
+
# yield subject, prediate, and literal to results.
|
149
|
+
end
|
148
150
|
yield RDF::Statement(subject, predicate, object, graph_name: graph_name, quoted: quoted)
|
149
151
|
end
|
150
152
|
end
|
151
153
|
end
|
152
|
-
end
|
153
|
-
|
154
|
-
subject
|
155
|
-
end
|
156
154
|
|
157
|
-
|
158
|
-
# Parse a List
|
159
|
-
#
|
160
|
-
# @param [Array] list
|
161
|
-
# The Array to serialize as a list
|
162
|
-
# @yield statement
|
163
|
-
# @yieldparam [RDF::Resource] statement
|
164
|
-
# @return [Array<RDF::Statement>]
|
165
|
-
# Statements for each item in the list
|
166
|
-
def parse_list(list, graph_name: nil, &block)
|
167
|
-
# log_debug('parse_list') {"list: #{list.inspect}"}
|
168
|
-
|
169
|
-
last = list.pop
|
170
|
-
result = first_bnode = last ? node : RDF.nil
|
171
|
-
|
172
|
-
list.each do |list_item|
|
173
|
-
# Set first to the result of the Object Converstion algorithm passing item.
|
174
|
-
object = item_to_rdf(list_item, graph_name: graph_name, &block)
|
175
|
-
yield RDF::Statement(first_bnode, RDF.first, object, graph_name: graph_name)
|
176
|
-
rest_bnode = node
|
177
|
-
yield RDF::Statement(first_bnode, RDF.rest, rest_bnode, graph_name: graph_name)
|
178
|
-
first_bnode = rest_bnode
|
155
|
+
subject
|
179
156
|
end
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
157
|
+
|
158
|
+
##
|
159
|
+
# Parse a List
|
160
|
+
#
|
161
|
+
# @param [Array] list
|
162
|
+
# The Array to serialize as a list
|
163
|
+
# @yield statement
|
164
|
+
# @yieldparam [RDF::Resource] statement
|
165
|
+
# @return [Array<RDF::Statement>]
|
166
|
+
# Statements for each item in the list
|
167
|
+
def parse_list(list, graph_name: nil, &block)
|
168
|
+
# log_debug('parse_list') {"list: #{list.inspect}"}
|
169
|
+
|
170
|
+
last = list.pop
|
171
|
+
result = first_bnode = last ? node : RDF.nil
|
172
|
+
|
173
|
+
list.each do |list_item|
|
174
|
+
# Set first to the result of the Object Converstion algorithm passing item.
|
175
|
+
object = item_to_rdf(list_item, graph_name: graph_name, &block)
|
176
|
+
yield RDF::Statement(first_bnode, RDF.first, object, graph_name: graph_name)
|
177
|
+
rest_bnode = node
|
178
|
+
yield RDF::Statement(first_bnode, RDF.rest, rest_bnode, graph_name: graph_name)
|
179
|
+
first_bnode = rest_bnode
|
180
|
+
end
|
181
|
+
if last
|
182
|
+
object = item_to_rdf(last, graph_name: graph_name, &block)
|
183
|
+
yield RDF::Statement(first_bnode, RDF.first, object, graph_name: graph_name)
|
184
|
+
yield RDF::Statement(first_bnode, RDF.rest, RDF.nil, graph_name: graph_name)
|
185
|
+
end
|
186
|
+
result
|
184
187
|
end
|
185
|
-
result
|
186
|
-
end
|
187
188
|
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
189
|
+
##
|
190
|
+
# Create a new named node using the sequence
|
191
|
+
def node
|
192
|
+
RDF::Node.new(namer.get_sym)
|
193
|
+
end
|
192
194
|
end
|
193
195
|
end
|
194
196
|
end
|