json-ld 3.1.3 → 3.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +7 -1
- data/VERSION +1 -1
- data/lib/json/ld.rb +3 -0
- data/lib/json/ld/api.rb +31 -24
- data/lib/json/ld/compact.rb +37 -21
- data/lib/json/ld/context.rb +532 -473
- data/lib/json/ld/expand.rb +131 -68
- data/lib/json/ld/from_rdf.rb +7 -8
- data/lib/json/ld/reader.rb +19 -10
- data/lib/json/ld/streaming_reader.rb +578 -0
- data/spec/context_spec.rb +4 -42
- data/spec/reader_spec.rb +33 -34
- data/spec/streaming_reader_spec.rb +237 -0
- data/spec/suite_helper.rb +14 -8
- metadata +6 -3
data/lib/json/ld/expand.rb
CHANGED
@@ -21,20 +21,21 @@ module JSON::LD
|
|
21
21
|
# @param [Array, Hash] input
|
22
22
|
# @param [String] active_property
|
23
23
|
# @param [Context] context
|
24
|
-
# @param [Boolean] ordered (true)
|
25
|
-
# Ensure output objects have keys ordered properly
|
26
24
|
# @param [Boolean] framing (false)
|
27
25
|
# Special rules for expanding a frame
|
28
26
|
# @param [Boolean] from_map
|
29
27
|
# Expanding from a map, which could be an `@type` map, so don't clear out context term definitions
|
28
|
+
#
|
30
29
|
# @return [Array<Hash{String => Object}>]
|
31
|
-
def expand(input, active_property, context,
|
32
|
-
|
30
|
+
def expand(input, active_property, context,
|
31
|
+
framing: false, from_map: false, log_depth: nil)
|
32
|
+
log_debug("expand", depth: log_depth.to_i) {"input: #{input.inspect}, active_property: #{active_property.inspect}, context: #{context.inspect}"}
|
33
33
|
framing = false if active_property == '@default'
|
34
|
-
expanded_active_property = context.expand_iri(active_property, vocab: true, as_string: true) if active_property
|
34
|
+
expanded_active_property = context.expand_iri(active_property, vocab: true, as_string: true, base: @options[:base]) if active_property
|
35
35
|
|
36
36
|
# Use a term-specific context, if defined, based on the non-type-scoped context.
|
37
37
|
property_scoped_context = context.term_definitions[active_property].context if active_property && context.term_definitions[active_property]
|
38
|
+
log_debug("expand", depth: log_depth.to_i) {"property_scoped_context: #{property_scoped_context.inspect}"} unless property_scoped_context.nil?
|
38
39
|
|
39
40
|
result = case input
|
40
41
|
when Array
|
@@ -42,7 +43,10 @@ module JSON::LD
|
|
42
43
|
is_list = context.container(active_property).include?('@list')
|
43
44
|
value = input.each_with_object([]) do |v, memo|
|
44
45
|
# Initialize expanded item to the result of using this algorithm recursively, passing active context, active property, and item as element.
|
45
|
-
v = expand(v, active_property, context,
|
46
|
+
v = expand(v, active_property, context,
|
47
|
+
framing: framing,
|
48
|
+
from_map: from_map,
|
49
|
+
log_depth: log_depth.to_i + 1)
|
46
50
|
|
47
51
|
# If the active property is @list or its container mapping is set to @list and v is an array, change it to a list object
|
48
52
|
v = {"@list" => v} if is_list && v.is_a?(Array)
|
@@ -57,23 +61,29 @@ module JSON::LD
|
|
57
61
|
value
|
58
62
|
when Hash
|
59
63
|
if context.previous_context
|
60
|
-
expanded_key_map = input.keys.inject({})
|
64
|
+
expanded_key_map = input.keys.inject({}) do |memo, key|
|
65
|
+
memo.merge(key => context.expand_iri(key, vocab: true, as_string: true, base: @options[:base]))
|
66
|
+
end
|
61
67
|
# Revert any previously type-scoped term definitions, unless this is from a map, a value object or a subject reference
|
62
68
|
revert_context = !from_map &&
|
63
69
|
!expanded_key_map.values.include?('@value') &&
|
64
70
|
!(expanded_key_map.values == ['@id'])
|
65
71
|
|
66
72
|
# If there's a previous context, the context was type-scoped
|
73
|
+
log_debug("expand", depth: log_depth.to_i) {"previous_context: #{context.previous_context.inspect}"} if revert_context
|
67
74
|
context = context.previous_context if revert_context
|
68
75
|
end
|
69
76
|
|
70
77
|
# Apply property-scoped context after reverting term-scoped context
|
71
|
-
|
78
|
+
unless property_scoped_context.nil?
|
79
|
+
context = context.parse(property_scoped_context, base: @options[:base], override_protected: true)
|
80
|
+
end
|
81
|
+
log_debug("expand", depth: log_depth.to_i) {"after property_scoped_context: #{context.inspect}"} unless property_scoped_context.nil?
|
72
82
|
|
73
83
|
# If element contains the key @context, set active context to the result of the Context Processing algorithm, passing active context and the value of the @context key as local context.
|
74
84
|
if input.has_key?('@context')
|
75
|
-
context = context.parse(input.delete('@context'))
|
76
|
-
log_debug("expand") {"context: #{context.inspect}"}
|
85
|
+
context = context.parse(input.delete('@context'), base: @options[:base])
|
86
|
+
log_debug("expand", depth: log_depth.to_i) {"context: #{context.inspect}"}
|
77
87
|
end
|
78
88
|
|
79
89
|
# Set the type-scoped context to the context on input, for use later
|
@@ -84,25 +94,28 @@ module JSON::LD
|
|
84
94
|
# See if keys mapping to @type have terms with a local context
|
85
95
|
type_key = nil
|
86
96
|
input.keys.sort.
|
87
|
-
select {|k| context.expand_iri(k, vocab: true,
|
97
|
+
select {|k| context.expand_iri(k, vocab: true, base: @options[:base]) == '@type'}.
|
88
98
|
each do |tk|
|
89
99
|
|
90
100
|
type_key ||= tk # Side effect saves the first found key mapping to @type
|
91
101
|
Array(input[tk]).sort.each do |term|
|
92
102
|
term_context = type_scoped_context.term_definitions[term].context if type_scoped_context.term_definitions[term]
|
93
|
-
|
103
|
+
unless term_context.nil?
|
104
|
+
log_debug("expand", depth: log_depth.to_i) {"term_context: #{term_context.inspect}"}
|
105
|
+
context = context.parse(term_context, base: @options[:base], propagate: false)
|
106
|
+
end
|
94
107
|
end
|
95
108
|
end
|
96
109
|
|
97
110
|
# Process each key and value in element. Ignores @nesting content
|
98
111
|
expand_object(input, active_property, context, output_object,
|
99
112
|
expanded_active_property: expanded_active_property,
|
100
|
-
|
113
|
+
framing: framing,
|
101
114
|
type_key: type_key,
|
102
|
-
|
103
|
-
|
115
|
+
type_scoped_context: type_scoped_context,
|
116
|
+
log_depth: log_depth.to_i + 1)
|
104
117
|
|
105
|
-
log_debug("output object") {output_object.inspect}
|
118
|
+
log_debug("output object", depth: log_depth.to_i) {output_object.inspect}
|
106
119
|
|
107
120
|
# If result contains the key @value:
|
108
121
|
if value?(output_object)
|
@@ -110,13 +123,13 @@ module JSON::LD
|
|
110
123
|
unless (keys - KEYS_VALUE_LANGUAGE_TYPE_INDEX_DIRECTION).empty?
|
111
124
|
# The result must not contain any keys other than @direction, @value, @language, @type, and @index. It must not contain both the @language key and the @type key. Otherwise, an invalid value object error has been detected and processing is aborted.
|
112
125
|
raise JsonLdError::InvalidValueObject,
|
113
|
-
|
126
|
+
"value object has unknown keys: #{output_object.inspect}"
|
114
127
|
end
|
115
128
|
|
116
129
|
if keys.include?('@type') && !(keys & %w(@language @direction)).empty?
|
117
130
|
# @type is inconsistent with either @language or @direction
|
118
131
|
raise JsonLdError::InvalidValueObject,
|
119
|
-
|
132
|
+
"value object must not include @type with either @language or @direction: #{output_object.inspect}"
|
120
133
|
end
|
121
134
|
|
122
135
|
output_object.delete('@language') if output_object.key?('@language') && Array(output_object['@language']).empty?
|
@@ -161,12 +174,12 @@ module JSON::LD
|
|
161
174
|
if (expanded_active_property || '@graph') == '@graph' &&
|
162
175
|
(output_object.key?('@value') || output_object.key?('@list') ||
|
163
176
|
(output_object.keys - KEY_ID).empty? && !framing)
|
164
|
-
log_debug(" =>") { "empty top-level: " + output_object.inspect}
|
177
|
+
log_debug(" =>", depth: log_depth.to_i) { "empty top-level: " + output_object.inspect}
|
165
178
|
return nil
|
166
179
|
end
|
167
180
|
|
168
181
|
# Re-order result keys if ordering
|
169
|
-
if ordered
|
182
|
+
if @options[:ordered]
|
170
183
|
output_object.keys.sort.each_with_object({}) {|kk, memo| memo[kk] = output_object[kk]}
|
171
184
|
else
|
172
185
|
output_object
|
@@ -176,12 +189,17 @@ module JSON::LD
|
|
176
189
|
return nil if input.nil? || active_property.nil? || expanded_active_property == '@graph'
|
177
190
|
|
178
191
|
# Apply property-scoped context
|
179
|
-
|
192
|
+
unless property_scoped_context.nil?
|
193
|
+
context = context.parse(property_scoped_context,
|
194
|
+
base: @options[:base],
|
195
|
+
override_protected: true)
|
196
|
+
end
|
197
|
+
log_debug("expand", depth: log_depth.to_i) {"property_scoped_context: #{context.inspect}"} unless property_scoped_context.nil?
|
180
198
|
|
181
|
-
context.expand_value(active_property, input,
|
199
|
+
context.expand_value(active_property, input, base: @options[:base])
|
182
200
|
end
|
183
201
|
|
184
|
-
log_debug {" => #{result.inspect}"}
|
202
|
+
log_debug(depth: log_depth.to_i) {" => #{result.inspect}"}
|
185
203
|
result
|
186
204
|
end
|
187
205
|
|
@@ -190,21 +208,21 @@ module JSON::LD
|
|
190
208
|
# Expand each key and value of element adding them to result
|
191
209
|
def expand_object(input, active_property, context, output_object,
|
192
210
|
expanded_active_property:,
|
193
|
-
|
211
|
+
framing:,
|
194
212
|
type_key:,
|
195
|
-
|
196
|
-
|
213
|
+
type_scoped_context:,
|
214
|
+
log_depth: nil)
|
197
215
|
nests = []
|
198
216
|
|
199
217
|
input_type = Array(input[type_key]).last
|
200
|
-
input_type = context.expand_iri(input_type, vocab: true, as_string: true) if input_type
|
218
|
+
input_type = context.expand_iri(input_type, vocab: true, as_string: true, base: @options[:base]) if input_type
|
201
219
|
|
202
220
|
# Then, proceed and process each property and value in element as follows:
|
203
|
-
keys = ordered ? input.keys.sort : input.keys
|
221
|
+
keys = @options[:ordered] ? input.keys.sort : input.keys
|
204
222
|
keys.each do |key|
|
205
223
|
# For each key and value in element, ordered lexicographically by key:
|
206
224
|
value = input[key]
|
207
|
-
expanded_property = context.expand_iri(key, vocab: true)
|
225
|
+
expanded_property = context.expand_iri(key, vocab: true, base: @options[:base])
|
208
226
|
|
209
227
|
# If expanded property is null or it neither contains a colon (:) nor it is a keyword, drop key by continuing to the next key.
|
210
228
|
next if expanded_property.is_a?(RDF::URI) && expanded_property.relative?
|
@@ -215,10 +233,10 @@ module JSON::LD
|
|
215
233
|
expanded_property.to_s.start_with?("_:") &&
|
216
234
|
context.processingMode('json-ld-1.1')
|
217
235
|
|
218
|
-
#log_debug("expand property") {"ap: #{active_property.inspect}, expanded: #{expanded_property.inspect}, value: #{value.inspect}"}
|
236
|
+
#log_debug("expand property", depth: log_depth.to_i) {"ap: #{active_property.inspect}, expanded: #{expanded_property.inspect}, value: #{value.inspect}"}
|
219
237
|
|
220
238
|
if expanded_property.nil?
|
221
|
-
#log_debug(" => ") {"skip nil property"}
|
239
|
+
#log_debug(" => ", depth: log_depth.to_i) {"skip nil property"}
|
222
240
|
next
|
223
241
|
end
|
224
242
|
|
@@ -236,16 +254,16 @@ module JSON::LD
|
|
236
254
|
# If expanded property is @id and value is not a string, an invalid @id value error has been detected and processing is aborted
|
237
255
|
e_id = case value
|
238
256
|
when String
|
239
|
-
context.expand_iri(value,
|
257
|
+
context.expand_iri(value, as_string: true, base: @options[:base], documentRelative: true)
|
240
258
|
when Array
|
241
259
|
# Framing allows an array of IRIs, and always puts values in an array
|
242
260
|
raise JsonLdError::InvalidIdValue,
|
243
261
|
"value of @id must be a string unless framing: #{value.inspect}" unless framing
|
244
|
-
context.expand_iri(value,
|
262
|
+
context.expand_iri(value, as_string: true, base: @options[:base], documentRelative: true)
|
245
263
|
value.map do |v|
|
246
264
|
raise JsonLdError::InvalidTypeValue,
|
247
265
|
"@id value must be a string or array of strings for framing: #{v.inspect}" unless v.is_a?(String)
|
248
|
-
context.expand_iri(v,
|
266
|
+
context.expand_iri(v, as_string: true, base: @options[:base], documentRelative: true)
|
249
267
|
end
|
250
268
|
when Hash
|
251
269
|
raise JsonLdError::InvalidIdValue,
|
@@ -268,7 +286,9 @@ module JSON::LD
|
|
268
286
|
when '@included'
|
269
287
|
# Included blocks are treated as an array of separate object nodes sharing the same referencing active_property. For 1.0, it is skipped as are other unknown keywords
|
270
288
|
next if context.processingMode('json-ld-1.0')
|
271
|
-
included_result = as_array(expand(value, active_property, context,
|
289
|
+
included_result = as_array(expand(value, active_property, context,
|
290
|
+
framing: framing,
|
291
|
+
log_depth: log_depth.to_i + 1))
|
272
292
|
|
273
293
|
# Expanded values must be node objects
|
274
294
|
raise JsonLdError::InvalidIncludedValue, "values of @included must expand to node objects" unless included_result.all? {|e| node?(e)}
|
@@ -276,27 +296,39 @@ module JSON::LD
|
|
276
296
|
Array(output_object['@included']) + included_result
|
277
297
|
when '@type'
|
278
298
|
# If expanded property is @type and value is neither a string nor an array of strings, an invalid type value error has been detected and processing is aborted. Otherwise, set expanded value to the result of using the IRI Expansion algorithm, passing active context, true for vocab, and true for document relative to expand the value or each of its items.
|
279
|
-
#log_debug("@type") {"value: #{value.inspect}"}
|
299
|
+
#log_debug("@type", depth: log_depth.to_i) {"value: #{value.inspect}"}
|
280
300
|
e_type = case value
|
281
301
|
when Array
|
282
302
|
value.map do |v|
|
283
303
|
raise JsonLdError::InvalidTypeValue,
|
284
304
|
"@type value must be a string or array of strings: #{v.inspect}" unless v.is_a?(String)
|
285
|
-
type_scoped_context.expand_iri(v,
|
305
|
+
type_scoped_context.expand_iri(v,
|
306
|
+
as_string: true,
|
307
|
+
base: @options[:base],
|
308
|
+
documentRelative: true,
|
309
|
+
vocab: true)
|
286
310
|
end
|
287
311
|
when String
|
288
|
-
type_scoped_context.expand_iri(value,
|
312
|
+
type_scoped_context.expand_iri(value,
|
313
|
+
as_string: true,
|
314
|
+
base: @options[:base],
|
315
|
+
documentRelative: true,
|
316
|
+
vocab: true)
|
289
317
|
when Hash
|
290
318
|
if !framing
|
291
319
|
raise JsonLdError::InvalidTypeValue,
|
292
320
|
"@type value must be a string or array of strings: #{value.inspect}"
|
293
321
|
elsif value.keys.length == 1 &&
|
294
|
-
type_scoped_context.expand_iri(value.keys.first, vocab: true) == '@default'
|
322
|
+
type_scoped_context.expand_iri(value.keys.first, vocab: true, base: @options[:base]) == '@default'
|
295
323
|
# Expand values of @default, which must be a string, or array of strings expanding to IRIs
|
296
324
|
[{'@default' => Array(value['@default']).map do |v|
|
297
325
|
raise JsonLdError::InvalidTypeValue,
|
298
326
|
"@type default value must be a string or array of strings: #{v.inspect}" unless v.is_a?(String)
|
299
|
-
type_scoped_context.expand_iri(v,
|
327
|
+
type_scoped_context.expand_iri(v,
|
328
|
+
as_string: true,
|
329
|
+
base: @options[:base],
|
330
|
+
documentRelative: true,
|
331
|
+
vocab: true)
|
300
332
|
end}]
|
301
333
|
elsif !value.empty?
|
302
334
|
raise JsonLdError::InvalidTypeValue,
|
@@ -314,7 +346,9 @@ module JSON::LD
|
|
314
346
|
framing || e_type.length > 1 ? e_type : e_type.first
|
315
347
|
when '@graph'
|
316
348
|
# If expanded property is @graph, set expanded value to the result of using this algorithm recursively passing active context, @graph for active property, and value for element.
|
317
|
-
value = expand(value, '@graph', context,
|
349
|
+
value = expand(value, '@graph', context,
|
350
|
+
framing: framing,
|
351
|
+
log_depth: log_depth.to_i + 1)
|
318
352
|
as_array(value)
|
319
353
|
when '@value'
|
320
354
|
# If expanded property is @value and input contains @type: json, accept any value.
|
@@ -406,7 +440,9 @@ module JSON::LD
|
|
406
440
|
next if (expanded_active_property || '@graph') == '@graph'
|
407
441
|
|
408
442
|
# Otherwise, initialize expanded value to the result of using this algorithm recursively passing active context, active property, and value for element.
|
409
|
-
value = expand(value, active_property, context,
|
443
|
+
value = expand(value, active_property, context,
|
444
|
+
framing: framing,
|
445
|
+
log_depth: log_depth.to_i + 1)
|
410
446
|
|
411
447
|
# Spec FIXME: need to be sure that result is an array
|
412
448
|
value = as_array(value)
|
@@ -414,7 +450,9 @@ module JSON::LD
|
|
414
450
|
value
|
415
451
|
when '@set'
|
416
452
|
# If expanded property is @set, set expanded value to the result of using this algorithm recursively, passing active context, active property, and value for element.
|
417
|
-
expand(value, active_property, context,
|
453
|
+
expand(value, active_property, context,
|
454
|
+
framing: framing,
|
455
|
+
log_depth: log_depth.to_i + 1)
|
418
456
|
when '@reverse'
|
419
457
|
# If expanded property is @reverse and value is not a JSON object, an invalid @reverse value error has been detected and processing is aborted.
|
420
458
|
raise JsonLdError::InvalidReverseValue,
|
@@ -422,11 +460,13 @@ module JSON::LD
|
|
422
460
|
|
423
461
|
# Otherwise
|
424
462
|
# Initialize expanded value to the result of using this algorithm recursively, passing active context, @reverse as active property, and value as element.
|
425
|
-
value = expand(value, '@reverse', context,
|
463
|
+
value = expand(value, '@reverse', context,
|
464
|
+
framing: framing,
|
465
|
+
log_depth: log_depth.to_i + 1)
|
426
466
|
|
427
467
|
# If expanded value contains an @reverse member, i.e., properties that are reversed twice, execute for each of its property and item the following steps:
|
428
468
|
if value.has_key?('@reverse')
|
429
|
-
#log_debug("@reverse") {"double reverse: #{value.inspect}"}
|
469
|
+
#log_debug("@reverse", depth: log_depth.to_i) {"double reverse: #{value.inspect}"}
|
430
470
|
value['@reverse'].each do |property, item|
|
431
471
|
# If result does not have a property member, create one and set its value to an empty array.
|
432
472
|
# Append item to the value of the property member of result.
|
@@ -455,7 +495,10 @@ module JSON::LD
|
|
455
495
|
when '@default', '@embed', '@explicit', '@omitDefault', '@preserve', '@requireAll'
|
456
496
|
next unless framing
|
457
497
|
# Framing keywords
|
458
|
-
[expand(value, expanded_property, context,
|
498
|
+
[expand(value, expanded_property, context,
|
499
|
+
framing: framing,
|
500
|
+
log_depth: log_depth.to_i + 1)
|
501
|
+
].flatten
|
459
502
|
when '@nest'
|
460
503
|
# Add key to nests
|
461
504
|
nests << key
|
@@ -467,7 +510,7 @@ module JSON::LD
|
|
467
510
|
end
|
468
511
|
|
469
512
|
# Unless expanded value is null, set the expanded property member of result to expanded value.
|
470
|
-
#log_debug("expand #{expanded_property}") { expanded_value.inspect}
|
513
|
+
#log_debug("expand #{expanded_property}", depth: log_depth.to_i) { expanded_value.inspect}
|
471
514
|
output_object[expanded_property] = expanded_value unless expanded_value.nil? && expanded_property == '@value' && input_type != '@json'
|
472
515
|
next
|
473
516
|
end
|
@@ -483,9 +526,9 @@ module JSON::LD
|
|
483
526
|
ary = []
|
484
527
|
|
485
528
|
# For each key-value pair language-language value in value, ordered lexicographically by language
|
486
|
-
keys = ordered ? value.keys.sort : value.keys
|
529
|
+
keys = @options[:ordered] ? value.keys.sort : value.keys
|
487
530
|
keys.each do |k|
|
488
|
-
expanded_k = context.expand_iri(k, vocab: true, as_string: true)
|
531
|
+
expanded_k = context.expand_iri(k, vocab: true, as_string: true, base: @options[:base])
|
489
532
|
|
490
533
|
if k !~ /^[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*$/ && expanded_k != '@none'
|
491
534
|
warn "@language must be valid BCP47: #{k.inspect}"
|
@@ -517,23 +560,35 @@ module JSON::LD
|
|
517
560
|
context.previous_context
|
518
561
|
elsif container.include?('@id') && context.term_definitions[key]
|
519
562
|
id_context = context.term_definitions[key].context if context.term_definitions[key]
|
520
|
-
id_context
|
563
|
+
if id_context.nil?
|
564
|
+
context
|
565
|
+
else
|
566
|
+
log_debug("expand", depth: log_depth.to_i) {"id_context: #{id_context.inspect}"}
|
567
|
+
context.parse(id_context, base: @options[:base], propagate: false)
|
568
|
+
end
|
521
569
|
else
|
522
570
|
context
|
523
571
|
end
|
524
572
|
|
525
573
|
# For each key-value in the object:
|
526
|
-
keys = ordered ? value.keys.sort : value.keys
|
574
|
+
keys = @options[:ordered] ? value.keys.sort : value.keys
|
527
575
|
keys.each do |k|
|
528
576
|
# If container mapping in the active context includes @type, and k is a term in the active context having a local context, use that context when expanding values
|
529
577
|
map_context = container_context.term_definitions[k].context if container.include?('@type') && container_context.term_definitions[k]
|
530
|
-
map_context
|
578
|
+
unless map_context.nil?
|
579
|
+
log_debug("expand", depth: log_depth.to_i) {"map_context: #{map_context.inspect}"}
|
580
|
+
map_context = container_context.parse(map_context, base: @options[:base],
|
581
|
+
propagate: false)
|
582
|
+
end
|
531
583
|
map_context ||= container_context
|
532
584
|
|
533
|
-
expanded_k = container_context.expand_iri(k, vocab: true, as_string: true)
|
585
|
+
expanded_k = container_context.expand_iri(k, vocab: true, as_string: true, base: @options[:base])
|
534
586
|
|
535
587
|
# Initialize index value to the result of using this algorithm recursively, passing active context, key as active property, and index value as element.
|
536
|
-
index_value = expand([value[k]].flatten, key, map_context,
|
588
|
+
index_value = expand([value[k]].flatten, key, map_context,
|
589
|
+
framing: framing,
|
590
|
+
from_map: true,
|
591
|
+
log_depth: log_depth.to_i + 1)
|
537
592
|
index_value.each do |item|
|
538
593
|
case
|
539
594
|
when container.include?('@index')
|
@@ -547,8 +602,8 @@ module JSON::LD
|
|
547
602
|
raise JsonLdError::InvalidValueObject, "Attempt to add illegal key to value object: #{index_key}"
|
548
603
|
else
|
549
604
|
# Expand key based on term
|
550
|
-
expanded_k = k == '@none' ? '@none' : container_context.expand_value(index_key, k)
|
551
|
-
index_property = container_context.expand_iri(index_key, vocab: true, as_string: true)
|
605
|
+
expanded_k = k == '@none' ? '@none' : container_context.expand_value(index_key, k, base: @options[:base])
|
606
|
+
index_property = container_context.expand_iri(index_key, vocab: true, as_string: true, base: @options[:base])
|
552
607
|
item[index_property] = [expanded_k].concat(Array(item[index_property])) unless expanded_k == '@none'
|
553
608
|
end
|
554
609
|
when container.include?('@id')
|
@@ -557,7 +612,7 @@ module JSON::LD
|
|
557
612
|
item = {'@graph' => as_array(item)}
|
558
613
|
end
|
559
614
|
# Expand k document relative
|
560
|
-
expanded_k = container_context.expand_iri(k,
|
615
|
+
expanded_k = container_context.expand_iri(k, as_string: true, base: @options[:base], documentRelative: true) unless expanded_k == '@none'
|
561
616
|
item['@id'] ||= expanded_k unless expanded_k == '@none'
|
562
617
|
when container.include?('@type')
|
563
618
|
item['@type'] = [expanded_k].concat(Array(item['@type'])) unless expanded_k == '@none'
|
@@ -570,26 +625,28 @@ module JSON::LD
|
|
570
625
|
ary
|
571
626
|
else
|
572
627
|
# Otherwise, initialize expanded value to the result of using this algorithm recursively, passing active context, key for active property, and value for element.
|
573
|
-
expand(value, key, context,
|
628
|
+
expand(value, key, context,
|
629
|
+
framing: framing,
|
630
|
+
log_depth: log_depth.to_i + 1)
|
574
631
|
end
|
575
632
|
|
576
633
|
# If expanded value is null, ignore key by continuing to the next key from element.
|
577
634
|
if expanded_value.nil?
|
578
|
-
#log_debug(" => skip nil value")
|
635
|
+
#log_debug(" => skip nil value", depth: log_depth.to_i)
|
579
636
|
next
|
580
637
|
end
|
581
|
-
#log_debug {" => #{expanded_value.inspect}"}
|
638
|
+
#log_debug(depth: log_depth.to_i) {" => #{expanded_value.inspect}"}
|
582
639
|
|
583
640
|
# If the container mapping associated to key in active context is @list and expanded value is not already a list object, convert expanded value to a list object by first setting it to an array containing only expanded value if it is not already an array, and then by setting it to a JSON object containing the key-value pair @list-expanded value.
|
584
641
|
if container.first == '@list' && container.length == 1 && !list?(expanded_value)
|
585
|
-
#log_debug(" => ") { "convert #{expanded_value.inspect} to list"}
|
642
|
+
#log_debug(" => ", depth: log_depth.to_i) { "convert #{expanded_value.inspect} to list"}
|
586
643
|
expanded_value = {'@list' => as_array(expanded_value)}
|
587
644
|
end
|
588
|
-
#log_debug {" => #{expanded_value.inspect}"}
|
645
|
+
#log_debug(depth: log_depth.to_i) {" => #{expanded_value.inspect}"}
|
589
646
|
|
590
647
|
# convert expanded value to @graph if container specifies it
|
591
648
|
if container.first == '@graph' && container.length == 1
|
592
|
-
#log_debug(" => ") { "convert #{expanded_value.inspect} to list"}
|
649
|
+
#log_debug(" => ", depth: log_depth.to_i) { "convert #{expanded_value.inspect} to list"}
|
593
650
|
expanded_value = as_array(expanded_value).map do |v|
|
594
651
|
{'@graph' => as_array(v)}
|
595
652
|
end
|
@@ -626,17 +683,23 @@ module JSON::LD
|
|
626
683
|
# For each key in nests, recusively expand content
|
627
684
|
nests.each do |key|
|
628
685
|
nest_context = context.term_definitions[key].context if context.term_definitions[key]
|
629
|
-
nest_context = nest_context
|
686
|
+
nest_context = if nest_context.nil?
|
687
|
+
context
|
688
|
+
else
|
689
|
+
log_debug("expand", depth: log_depth.to_i) {"nest_context: #{nest_context.inspect}"}
|
690
|
+
context.parse(nest_context, base: @options[:base],
|
691
|
+
override_protected: true)
|
692
|
+
end
|
630
693
|
nested_values = as_array(input[key])
|
631
694
|
nested_values.each do |nv|
|
632
695
|
raise JsonLdError::InvalidNestValue, nv.inspect unless
|
633
|
-
nv.is_a?(Hash) && nv.keys.none? {|k| nest_context.expand_iri(k, vocab: true) == '@value'}
|
696
|
+
nv.is_a?(Hash) && nv.keys.none? {|k| nest_context.expand_iri(k, vocab: true, base: @options[:base]) == '@value'}
|
634
697
|
expand_object(nv, active_property, nest_context, output_object,
|
698
|
+
framing: framing,
|
635
699
|
expanded_active_property: expanded_active_property,
|
636
|
-
type_scoped_context: type_scoped_context,
|
637
700
|
type_key: type_key,
|
638
|
-
|
639
|
-
|
701
|
+
type_scoped_context: type_scoped_context,
|
702
|
+
log_depth: log_depth.to_i + 1)
|
640
703
|
end
|
641
704
|
end
|
642
705
|
end
|