json-ld 2.1.2 → 2.1.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 +4 -4
- data/README.md +107 -4
- data/VERSION +1 -1
- data/lib/json/ld.rb +38 -33
- data/lib/json/ld/api.rb +27 -14
- data/lib/json/ld/compact.rb +65 -10
- data/lib/json/ld/context.rb +158 -22
- data/lib/json/ld/expand.rb +339 -279
- data/lib/json/ld/frame.rb +30 -5
- data/lib/json/ld/from_rdf.rb +4 -3
- data/spec/compact_spec.rb +1107 -328
- data/spec/context_spec.rb +153 -27
- data/spec/expand_spec.rb +907 -152
- data/spec/format_spec.rb +1 -1
- data/spec/frame_spec.rb +90 -24
- data/spec/spec_helper.rb +0 -6
- data/spec/streaming_writer_spec.rb +2 -2
- data/spec/suite_helper.rb +2 -3
- data/spec/writer_spec.rb +2 -2
- metadata +7 -49
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2089bccb0e9e19a4f349908dd6456c908a653e9f
|
4
|
+
data.tar.gz: 97c3aef58769ce0c233d85e027fca1e0bb660fd6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 625898c1cbb1f6dbe8a2a4fce2067f6702a3205911099878d1fecaad97dd18c014ff0dcea995d90885e13fff67f04362a6b8efe1fdbad8ac7c5a62b09070c28d
|
7
|
+
data.tar.gz: 8501add1dca033f2b2c61966bf4425aeed1f1852b39b1b9dabeb2253510c56b87b70d8c480652dcc0ac4c28ef078218915554c2037c747ac939b06b65d6d4781
|
data/README.md
CHANGED
@@ -14,6 +14,8 @@ JSON::LD can now be used to create a _context_ from an RDFS/OWL definition, and
|
|
14
14
|
|
15
15
|
If the [jsonlint][] gem is installed, it will be used when validating an input document.
|
16
16
|
|
17
|
+
[Implementation Report](file.earl.html)
|
18
|
+
|
17
19
|
Install with `gem install json-ld`
|
18
20
|
|
19
21
|
### MultiJson parser
|
@@ -45,9 +47,9 @@ This gem implements an optimized streaming writer used for generating JSON-LD fr
|
|
45
47
|
JSON::LD::API.expand(input) =>
|
46
48
|
|
47
49
|
[{
|
48
|
-
"http://xmlns.com/foaf/0.1/name": ["Manu Sporny"],
|
49
|
-
"http://xmlns.com/foaf/0.1/homepage": ["http://manu.sporny.org/"],
|
50
|
-
"http://xmlns.com/foaf/0.1/avatar": ["http://twitter.com/account/profile_image/manusporny"]
|
50
|
+
"http://xmlns.com/foaf/0.1/name": [{"@value"=>"Manu Sporny"}],
|
51
|
+
"http://xmlns.com/foaf/0.1/homepage": [{"@value"=>"http://manu.sporny.org/"}],
|
52
|
+
"http://xmlns.com/foaf/0.1/avatar": [{"@value": "http://twitter.com/account/profile_image/manusporny"}]
|
51
53
|
}]
|
52
54
|
|
53
55
|
### Compact a Document
|
@@ -261,6 +263,107 @@ A context may be serialized to Ruby to speed this process using `Context#to_rb`.
|
|
261
263
|
|
262
264
|
As JSON-LD may come from many different sources, included as an embedded script tag within an HTML document, the RDF Reader will strip input before the leading `{` or `[` and after the trailing `}` or `]`.
|
263
265
|
|
266
|
+
## Extensions from JSON-LD 1.0
|
267
|
+
This implementation is being used as a test-bed for features planned for an upcoming JSON-LD 1.1 Community release.
|
268
|
+
|
269
|
+
### Scoped Contexts
|
270
|
+
A term definition can include `@context`, which is applied to values of that object. This is also used when compacting. Taken together, this allows framing to effectively include context definitions more deeply within the framed structure.
|
271
|
+
|
272
|
+
{
|
273
|
+
"@context": {
|
274
|
+
"ex": "http://example.com/",
|
275
|
+
"foo": {
|
276
|
+
"@id": "ex:foo",
|
277
|
+
"@type": "@vocab"
|
278
|
+
"@context": {
|
279
|
+
"Bar": "ex:Bar",
|
280
|
+
"Baz": "ex:Baz"
|
281
|
+
}
|
282
|
+
}
|
283
|
+
},
|
284
|
+
"foo": "Bar"
|
285
|
+
}
|
286
|
+
|
287
|
+
### @id and @type maps
|
288
|
+
The value of `@container` in a term definition can include `@id` or `@type`, in addition to `@set`, `@list`, `@language`, and `@index`. This allows value indexing based on either the `@id` or `@type` of associated objects.
|
289
|
+
|
290
|
+
{
|
291
|
+
"@context": {
|
292
|
+
"@vocab": "http://example/",
|
293
|
+
"idmap": {"@container": "@id"}
|
294
|
+
},
|
295
|
+
"idmap": {
|
296
|
+
"http://example.org/foo": {"label": "Object with @id <foo>"},
|
297
|
+
"_:bar": {"label": "Object with @id _:bar"}
|
298
|
+
}
|
299
|
+
}
|
300
|
+
|
301
|
+
### Transparent Nesting
|
302
|
+
Many JSON APIs separate properties from their entities using an intermediate object. For example, a set of possible labels may be grouped under a common property:
|
303
|
+
|
304
|
+
{
|
305
|
+
"@context": {
|
306
|
+
"skos": "http://www.w3.org/2004/02/skos/core#",
|
307
|
+
"labels": "@nest",
|
308
|
+
"main_label": {"@id": "skos:prefLabel"},
|
309
|
+
"other_label": {"@id": "skos:altLabel"},
|
310
|
+
"homepage": {"@id":"http://schema.org/description", "@type":"@id"}
|
311
|
+
},
|
312
|
+
"@id":"http://example.org/myresource",
|
313
|
+
"homepage": "http://example.org",
|
314
|
+
"labels": {
|
315
|
+
"main_label": "This is the main label for my resource",
|
316
|
+
"other_label": "This is the other label"
|
317
|
+
}
|
318
|
+
}
|
319
|
+
|
320
|
+
In this case, the `labels` property is semantically meaningless. Defining it as equivalent to `@nest` causes it to be ignored when expanding, making it equivalent to the following:
|
321
|
+
|
322
|
+
{
|
323
|
+
"@context": {
|
324
|
+
"skos": "http://www.w3.org/2004/02/skos/core#",
|
325
|
+
"labels": "@nest",
|
326
|
+
"main_label": {"@id": "skos:prefLabel"},
|
327
|
+
"other_label": {"@id": "skos:altLabel"},
|
328
|
+
"homepage": {"@id":"http://schema.org/description", "@type":"@id"}
|
329
|
+
},
|
330
|
+
"@id":"http://example.org/myresource",
|
331
|
+
"homepage": "http://example.org",
|
332
|
+
"main_label": "This is the main label for my resource",
|
333
|
+
"other_label": "This is the other label"
|
334
|
+
}
|
335
|
+
|
336
|
+
Similarly, properties may be marked with "@nest": "nest-term", to cause them to be nested. Note that the `@nest` keyword can also be aliased in the context.
|
337
|
+
|
338
|
+
{
|
339
|
+
"@context": {
|
340
|
+
"skos": "http://www.w3.org/2004/02/skos/core#",
|
341
|
+
"labels": "@nest",
|
342
|
+
"main_label": {"@id": "skos:prefLabel", "@nest": "labels"},
|
343
|
+
"other_label": {"@id": "skos:altLabel", "@nest": "labels"},
|
344
|
+
"homepage": {"@id":"http://schema.org/description", "@type":"@id"}
|
345
|
+
},
|
346
|
+
"@id":"http://example.org/myresource",
|
347
|
+
"homepage": "http://example.org",
|
348
|
+
"labels": {
|
349
|
+
"main_label": "This is the main label for my resource",
|
350
|
+
"other_label": "This is the other label"
|
351
|
+
}
|
352
|
+
}
|
353
|
+
|
354
|
+
In this way, nesting survives round-tripping through expansion, and framed output can include nested properties.
|
355
|
+
|
356
|
+
### Framing Updates
|
357
|
+
The [JSON-LD Framing 1.1 Specification]() improves on previous un-released versions.
|
358
|
+
|
359
|
+
* [More Specific Frame matching](https://github.com/json-ld/json-ld.org/issues/110) – Allows framing to extend to elements of value objects, and objects are matched through recursive frame matching. `{}` is used as a wildcard, and `[]` as matching nothing.
|
360
|
+
* [Graph framing](https://github.com/json-ld/json-ld.org/issues/118) – previously, only the merged graph can be framed, this update allows arbitrary graphs to be framed.
|
361
|
+
* Use `@graph` in frame, matches the default graph, not the merged graph.
|
362
|
+
* Use `@graph` in property value, causes the apropriatly named graph to be used for filling in values.
|
363
|
+
* [Reverse properties](https://github.com/json-ld/json-ld.org/issues/311) – `@reverse` (or a property defined with `@reverse`) can cause matching values to be included, allowing a matched object to include reverse references to any objects referencing it.
|
364
|
+
* [@omitDefault behavior](https://github.com/json-ld/json-ld.org/issues/389) – In addition to `true` and `false`, `@omitDefault` can take `@last`, `@always`, `@never`, and `@link`.
|
365
|
+
* [multiple `@id` matching](https://github.com/json-ld/json-ld.org/issues/424) – A frame can match based on one or more specific object `@id` values.
|
366
|
+
|
264
367
|
## Documentation
|
265
368
|
Full documentation available on [RubyDoc](http://rubydoc.info/gems/json-ld/file/README.md)
|
266
369
|
|
@@ -286,7 +389,7 @@ Note, the API method signatures differed in versions before 1.0, in that they al
|
|
286
389
|
|
287
390
|
## Dependencies
|
288
391
|
* [Ruby](http://ruby-lang.org/) (>= 2.2.2)
|
289
|
-
* [RDF.rb](http://rubygems.org/gems/rdf) (>= 2.
|
392
|
+
* [RDF.rb](http://rubygems.org/gems/rdf) (>= 2.2)
|
290
393
|
* [JSON](https://rubygems.org/gems/json) (>= 1.5)
|
291
394
|
|
292
395
|
## Installation
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.1.
|
1
|
+
2.1.3
|
data/lib/json/ld.rb
CHANGED
@@ -34,7 +34,7 @@ module JSON
|
|
34
34
|
autoload :Resource, 'json/ld/resource'
|
35
35
|
autoload :VERSION, 'json/ld/version'
|
36
36
|
autoload :Writer, 'json/ld/writer'
|
37
|
-
|
37
|
+
|
38
38
|
# Initial context
|
39
39
|
# @see http://json-ld.org/spec/latest/json-ld-api/#appendix-b
|
40
40
|
INITIAL_CONTEXT = {
|
@@ -53,12 +53,14 @@ module JSON
|
|
53
53
|
@graph
|
54
54
|
@language
|
55
55
|
@list
|
56
|
+
@nest
|
56
57
|
@omitDefault
|
57
58
|
@requireAll
|
58
59
|
@reverse
|
59
60
|
@set
|
60
61
|
@type
|
61
62
|
@value
|
63
|
+
@version
|
62
64
|
@vocab
|
63
65
|
).freeze
|
64
66
|
|
@@ -87,7 +89,7 @@ module JSON
|
|
87
89
|
array_nl: "\n"
|
88
90
|
)
|
89
91
|
|
90
|
-
class JsonLdError <
|
92
|
+
class JsonLdError < StandardError
|
91
93
|
def to_s
|
92
94
|
"#{self.class.instance_variable_get :@code}: #{super}"
|
93
95
|
end
|
@@ -95,46 +97,49 @@ module JSON
|
|
95
97
|
self.class.instance_variable_get :@code
|
96
98
|
end
|
97
99
|
|
98
|
-
class
|
99
|
-
class
|
100
|
-
class InvalidIndexValue < JsonLdError; @code = "invalid @index value"; end
|
100
|
+
class CollidingKeywords < JsonLdError; @code = "colliding keywords"; end
|
101
|
+
class CompactionToListOfLists < JsonLdError; @code = "compaction to list of lists"; end
|
101
102
|
class ConflictingIndexes < JsonLdError; @code = "conflicting indexes"; end
|
102
|
-
class
|
103
|
-
class InvalidLocalContext < JsonLdError; @code = "invalid local context"; end
|
104
|
-
class MultipleContextLinkHeaders < JsonLdError; @code = "multiple context link headers"; end
|
105
|
-
class LoadingRemoteContextFailed < JsonLdError; @code = "loading remote context failed"; end
|
106
|
-
class InvalidRemoteContext < JsonLdError; @code = "invalid remote context"; end
|
107
|
-
class RecursiveContextInclusion < JsonLdError; @code = "recursive context inclusion"; end
|
103
|
+
class CyclicIRIMapping < JsonLdError; @code = "cyclic IRI mapping"; end
|
108
104
|
class InvalidBaseIRI < JsonLdError; @code = "invalid base IRI"; end
|
109
|
-
class
|
105
|
+
class InvalidContainerMapping < JsonLdError; @code = "invalid container mapping"; end
|
110
106
|
class InvalidDefaultLanguage < JsonLdError; @code = "invalid default language"; end
|
111
|
-
class
|
112
|
-
class
|
113
|
-
class
|
107
|
+
class InvalidIdValue < JsonLdError; @code = "invalid @id value"; end
|
108
|
+
class InvalidIndexValue < JsonLdError; @code = "invalid @index value"; end
|
109
|
+
class InvalidVersionValue < JsonLdError; @code = "invalid @version value"; end
|
114
110
|
class InvalidIRIMapping < JsonLdError; @code = "invalid IRI mapping"; end
|
115
|
-
class CyclicIRIMapping < JsonLdError; @code = "cyclic IRI mapping"; end
|
116
111
|
class InvalidKeywordAlias < JsonLdError; @code = "invalid keyword alias"; end
|
117
|
-
class InvalidTypeMapping < JsonLdError; @code = "invalid type mapping"; end
|
118
112
|
class InvalidLanguageMapping < JsonLdError; @code = "invalid language mapping"; end
|
119
|
-
class
|
120
|
-
class InvalidContainerMapping < JsonLdError; @code = "invalid container mapping"; end
|
121
|
-
class InvalidTypeValue < JsonLdError; @code = "invalid type value"; end
|
122
|
-
class InvalidValueObject < JsonLdError; @code = "invalid value object"; end
|
123
|
-
class InvalidValueObjectValue < JsonLdError; @code = "invalid value object value"; end
|
113
|
+
class InvalidLanguageMapValue < JsonLdError; @code = "invalid language map value"; end
|
124
114
|
class InvalidLanguageTaggedString < JsonLdError; @code = "invalid language-tagged string"; end
|
125
115
|
class InvalidLanguageTaggedValue < JsonLdError; @code = "invalid language-tagged value"; end
|
126
|
-
class
|
127
|
-
class
|
128
|
-
class
|
129
|
-
class
|
116
|
+
class InvalidLocalContext < JsonLdError; @code = "invalid local context"; end
|
117
|
+
class InvalidNestValue < JsonLdError; @code = "invalid @nest value"; end
|
118
|
+
class InvalidRemoteContext < JsonLdError; @code = "invalid remote context"; end
|
119
|
+
class InvalidReverseProperty < JsonLdError; @code = "invalid reverse property"; end
|
130
120
|
class InvalidReversePropertyMap < JsonLdError; @code = "invalid reverse property map"; end
|
131
|
-
class InvalidReverseValue < JsonLdError; @code = "invalid @reverse value"; end
|
132
121
|
class InvalidReversePropertyValue < JsonLdError; @code = "invalid reverse property value"; end
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
class
|
137
|
-
class
|
122
|
+
class InvalidReverseValue < JsonLdError; @code = "invalid @reverse value"; end
|
123
|
+
class InvalidScopedContext < JsonLdError; @code = "invalid scoped context"; end
|
124
|
+
class InvalidSetOrListObject < JsonLdError; @code = "invalid set or list object"; end
|
125
|
+
class InvalidTermDefinition < JsonLdError; @code = "invalid term definition"; end
|
126
|
+
class InvalidTypedValue < JsonLdError; @code = "invalid typed value"; end
|
127
|
+
class InvalidTypeMapping < JsonLdError; @code = "invalid type mapping"; end
|
128
|
+
class InvalidTypeValue < JsonLdError; @code = "invalid type value"; end
|
129
|
+
class InvalidValueObject < JsonLdError; @code = "invalid value object"; end
|
130
|
+
class InvalidValueObjectValue < JsonLdError; @code = "invalid value object value"; end
|
131
|
+
class InvalidVocabMapping < JsonLdError; @code = "invalid vocab mapping"; end
|
132
|
+
class KeywordRedefinition < JsonLdError; @code = "keyword redefinition"; end
|
133
|
+
class ListOfLists < JsonLdError; @code = "list of lists"; end
|
134
|
+
class LoadingDocumentFailed < JsonLdError; @code = "loading document failed"; end
|
135
|
+
class LoadingRemoteContextFailed < JsonLdError; @code = "loading remote context failed"; end
|
136
|
+
class MultipleContextLinkHeaders < JsonLdError; @code = "multiple context link headers"; end
|
137
|
+
class ProcessingModeConflict < JsonLdError; @code = "processing mode conflict"; end
|
138
|
+
class RecursiveContextInclusion < JsonLdError; @code = "recursive context inclusion"; end
|
139
|
+
class InvalidFrame < JsonLdError
|
140
|
+
class MultipleEmbeds < InvalidFrame; end
|
141
|
+
class Syntax < InvalidFrame; end
|
142
|
+
end
|
138
143
|
end
|
139
144
|
end
|
140
|
-
end
|
145
|
+
end
|
data/lib/json/ld/api.rb
CHANGED
@@ -69,10 +69,12 @@ module JSON::LD
|
|
69
69
|
# A context that is used to initialize the active context when expanding a document.
|
70
70
|
# @option options [Boolean, String, RDF::URI] :flatten
|
71
71
|
# If set to a value that is not `false`, the JSON-LD processor must modify the output of the Compaction Algorithm or the Expansion Algorithm by coalescing all properties associated with each subject via the Flattening Algorithm. The value of `flatten must` be either an _IRI_ value representing the name of the graph to flatten, or `true`. If the value is `true`, then the first graph encountered in the input document is selected and flattened.
|
72
|
-
# @option options [String] :processingMode
|
72
|
+
# @option options [String] :processingMode
|
73
73
|
# Processing mode, json-ld-1.0 or json-ld-1.1. Also can have other values:
|
74
74
|
#
|
75
75
|
# * json-ld-1.1-expand-frame – special frame expansion mode.
|
76
|
+
#
|
77
|
+
# If `processingMode` is not specified, a mode of `json-ld-1.0` or `json-ld-1.1` is set, the context used for `expansion` or `compaction`.
|
76
78
|
# @option options [Boolean] :rename_bnodes (true)
|
77
79
|
# Rename bnodes as part of expansion, or keep them the same.
|
78
80
|
# @option options [Boolean] :unique_bnodes (false)
|
@@ -88,10 +90,8 @@ module JSON::LD
|
|
88
90
|
@options = {
|
89
91
|
compactArrays: true,
|
90
92
|
rename_bnodes: true,
|
91
|
-
processingMode: "json-ld-1.1",
|
92
93
|
documentLoader: self.class.method(:documentLoader)
|
93
94
|
}
|
94
|
-
@options[:validate] = %w(json-ld-1.0 json-ld-1.1).include?(@options[:processingMode])
|
95
95
|
@options = @options.merge(options)
|
96
96
|
@namer = options[:unique_bnodes] ? BlankNodeUniqer.new : (@options[:rename_bnodes] ? BlankNodeNamer.new("b") : BlankNodeMapper.new)
|
97
97
|
|
@@ -135,6 +135,10 @@ module JSON::LD
|
|
135
135
|
context ||= (@value['@context'] if @value.is_a?(Hash)) || context_ref
|
136
136
|
@context = Context.parse(context || {}, @options)
|
137
137
|
|
138
|
+
# If not set explicitly, the context figures out the processing mode
|
139
|
+
@options[:processingMode] ||= @context.processingMode
|
140
|
+
@options[:validate] ||= %w(json-ld-1.0 json-ld-1.1).include?(@options[:processingMode])
|
141
|
+
|
138
142
|
if block_given?
|
139
143
|
case block.arity
|
140
144
|
when 0, -1 then instance_eval(&block)
|
@@ -207,7 +211,7 @@ module JSON::LD
|
|
207
211
|
expanded_input = options[:expanded] ? input : API.expand(input, options)
|
208
212
|
|
209
213
|
API.new(expanded_input, context, options) do
|
210
|
-
log_debug(".compact") {"expanded input: #{
|
214
|
+
log_debug(".compact") {"expanded input: #{expanded_input.to_json(JSON_STATE) rescue 'malformed json'}"}
|
211
215
|
result = compact(value)
|
212
216
|
|
213
217
|
# xxx) Add the given context to the output
|
@@ -298,6 +302,7 @@ module JSON::LD
|
|
298
302
|
# @option options [Boolean] :omitDefault (false)
|
299
303
|
# a flag specifying that properties that are missing from the JSON-LD input should be omitted from the output.
|
300
304
|
# @option options [Boolean] :expanded Input is already expanded
|
305
|
+
# @option options [Boolean] :pruneBlankNodeIdentifiers (true) removes blank node identifiers that are only used once.
|
301
306
|
# @yield jsonld
|
302
307
|
# @yieldparam [Hash] jsonld
|
303
308
|
# The framed JSON-LD document
|
@@ -309,13 +314,14 @@ module JSON::LD
|
|
309
314
|
def self.frame(input, frame, options = {})
|
310
315
|
result = nil
|
311
316
|
options = {
|
312
|
-
base:
|
313
|
-
compactArrays:
|
314
|
-
embed:
|
315
|
-
explicit:
|
316
|
-
requireAll:
|
317
|
-
omitDefault:
|
318
|
-
|
317
|
+
base: (input if input.is_a?(String)),
|
318
|
+
compactArrays: true,
|
319
|
+
embed: '@last',
|
320
|
+
explicit: false,
|
321
|
+
requireAll: true,
|
322
|
+
omitDefault: false,
|
323
|
+
pruneBlankNodeIdentifiers: true,
|
324
|
+
documentLoader: method(:documentLoader)
|
319
325
|
}.merge!(options)
|
320
326
|
|
321
327
|
framing_state = {
|
@@ -365,7 +371,12 @@ module JSON::LD
|
|
365
371
|
|
366
372
|
result = []
|
367
373
|
frame(framing_state, framing_state[:subjects].keys.sort, (expanded_frame.first || {}), options.merge(parent: result))
|
368
|
-
|
374
|
+
|
375
|
+
# Count blank node identifiers used in the document, if pruning
|
376
|
+
bnodes_to_clear = if options[:pruneBlankNodeIdentifiers]
|
377
|
+
count_blank_node_identifiers(result).collect {|k, v| k if v == 1}.compact
|
378
|
+
end
|
379
|
+
|
369
380
|
# Initalize context from frame
|
370
381
|
@context = @context.parse(frame['@context'])
|
371
382
|
# Compact result
|
@@ -376,7 +387,7 @@ module JSON::LD
|
|
376
387
|
kwgraph = context.compact_iri('@graph', quiet: true)
|
377
388
|
result = context.serialize.merge({kwgraph => compacted})
|
378
389
|
log_debug(".frame") {"after compact: #{result.to_json(JSON_STATE) rescue 'malformed json'}"}
|
379
|
-
result = cleanup_preserve(result)
|
390
|
+
result = cleanup_preserve(result, bnodes_to_clear || [])
|
380
391
|
end
|
381
392
|
|
382
393
|
block_given? ? yield(result) : result
|
@@ -450,6 +461,7 @@ module JSON::LD
|
|
450
461
|
# @option options (see #initialize)
|
451
462
|
# @option options [Boolean] :useRdfType (false)
|
452
463
|
# If set to `true`, the JSON-LD processor will treat `rdf:type` like a normal property instead of using `@type`.
|
464
|
+
# @option options [Boolean] :useNativeTypes (false) use native representations
|
453
465
|
# @yield jsonld
|
454
466
|
# @yieldparam [Hash] jsonld
|
455
467
|
# The JSON-LD document in expanded form
|
@@ -458,10 +470,11 @@ module JSON::LD
|
|
458
470
|
# If a block is given, the result of evaluating the block is returned, otherwise, the expanded JSON-LD document
|
459
471
|
def self.fromRdf(input, options = {}, &block)
|
460
472
|
useRdfType = options.fetch(:useRdfType, false)
|
473
|
+
useNativeTypes = options.fetch(:useNativeTypes, false)
|
461
474
|
result = nil
|
462
475
|
|
463
476
|
API.new(nil, nil, options) do |api|
|
464
|
-
result = api.from_statements(input, useRdfType: useRdfType)
|
477
|
+
result = api.from_statements(input, useRdfType: useRdfType, useNativeTypes: useNativeTypes)
|
465
478
|
end
|
466
479
|
|
467
480
|
block_given? ? yield(result) : result
|
data/lib/json/ld/compact.rb
CHANGED
@@ -16,6 +16,12 @@ module JSON::LD
|
|
16
16
|
#else
|
17
17
|
# log_debug("compact") {"property: #{property.inspect}"}
|
18
18
|
#end
|
19
|
+
|
20
|
+
# If the term definition for active property itself contains a context, use that for compacting values.
|
21
|
+
input_context = self.context
|
22
|
+
td = self.context.term_definitions[property] if property
|
23
|
+
self.context = (td && td.context && self.context.parse(td.context)) || input_context
|
24
|
+
|
19
25
|
case element
|
20
26
|
when Array
|
21
27
|
#log_debug("") {"Array #{element.inspect}"}
|
@@ -46,9 +52,9 @@ module JSON::LD
|
|
46
52
|
end
|
47
53
|
|
48
54
|
inside_reverse = property == '@reverse'
|
49
|
-
result = {}
|
55
|
+
result, nest_result = {}, nil
|
50
56
|
|
51
|
-
element.
|
57
|
+
element.keys.sort.each do |expanded_property|
|
52
58
|
expanded_value = element[expanded_property]
|
53
59
|
#log_debug("") {"#{expanded_property}: #{expanded_value.inspect}"}
|
54
60
|
|
@@ -56,6 +62,15 @@ module JSON::LD
|
|
56
62
|
compacted_value = [expanded_value].flatten.compact.map do |expanded_type|
|
57
63
|
context.compact_iri(expanded_type, vocab: (expanded_property == '@type'), log_depth: @options[:log_depth])
|
58
64
|
end
|
65
|
+
|
66
|
+
# If key is @type and any compacted value is a term having a local context, overlay that context.
|
67
|
+
if expanded_property == '@type'
|
68
|
+
compacted_value.each do |term|
|
69
|
+
term_context = self.context.term_definitions[term].context if context.term_definitions[term]
|
70
|
+
self.context = context.parse(term_context) if term_context
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
59
74
|
compacted_value = compacted_value.first if compacted_value.length == 1
|
60
75
|
|
61
76
|
al = context.compact_iri(expanded_property, vocab: true, quiet: true)
|
@@ -72,6 +87,7 @@ module JSON::LD
|
|
72
87
|
value = [value] if !value.is_a?(Array) &&
|
73
88
|
(context.container(prop) == '@set' || !@options[:compactArrays])
|
74
89
|
#log_debug("") {"merge #{prop} => #{value.inspect}"}
|
90
|
+
|
75
91
|
merge_compacted_value(result, prop, value)
|
76
92
|
compacted_value.delete(prop)
|
77
93
|
end
|
@@ -106,8 +122,14 @@ module JSON::LD
|
|
106
122
|
reverse: inside_reverse,
|
107
123
|
log_depth: @options[:log_depth])
|
108
124
|
|
109
|
-
|
110
|
-
|
125
|
+
if nest_prop = context.nest(item_active_property)
|
126
|
+
result[nest_prop] ||= {}
|
127
|
+
iap = result[result[nest_prop]] ||= []
|
128
|
+
result[nest_prop][item_active_property] = [iap] unless iap.is_a?(Array)
|
129
|
+
else
|
130
|
+
iap = result[item_active_property] ||= []
|
131
|
+
result[item_active_property] = [iap] unless iap.is_a?(Array)
|
132
|
+
end
|
111
133
|
end
|
112
134
|
|
113
135
|
# At this point, expanded value must be an array due to the Expansion algorithm.
|
@@ -119,6 +141,14 @@ module JSON::LD
|
|
119
141
|
reverse: inside_reverse,
|
120
142
|
log_depth: @options[:log_depth])
|
121
143
|
|
144
|
+
|
145
|
+
nest_result = if nest_prop = context.nest(item_active_property)
|
146
|
+
# FIXME??: It's possible that nest_prop will be used both for nesting, and for values of @nest
|
147
|
+
result[nest_prop] ||= {}
|
148
|
+
else
|
149
|
+
result
|
150
|
+
end
|
151
|
+
|
122
152
|
container = context.container(item_active_property)
|
123
153
|
value = list?(expanded_item) ? expanded_item['@list'] : expanded_item
|
124
154
|
compacted_item = compact(value, property: item_active_property)
|
@@ -135,14 +165,36 @@ module JSON::LD
|
|
135
165
|
end
|
136
166
|
else
|
137
167
|
raise JsonLdError::CompactionToListOfLists,
|
138
|
-
"key cannot have more than one list value" if
|
168
|
+
"key cannot have more than one list value" if nest_result.has_key?(item_active_property)
|
139
169
|
end
|
140
170
|
end
|
141
171
|
|
142
|
-
if %w(@language @index).include?(container)
|
143
|
-
map_object =
|
144
|
-
compacted_item =
|
145
|
-
|
172
|
+
if %w(@language @index @id @type).include?(container)
|
173
|
+
map_object = nest_result[item_active_property] ||= {}
|
174
|
+
compacted_item = case container
|
175
|
+
when '@id'
|
176
|
+
id_prop = context.compact_iri('@id', vocab: true, quiet: true)
|
177
|
+
map_key = compacted_item[id_prop]
|
178
|
+
map_key = context.compact_iri(map_key, quiet: true)
|
179
|
+
compacted_item.delete(id_prop)
|
180
|
+
compacted_item
|
181
|
+
when '@index'
|
182
|
+
map_key = expanded_item[container]
|
183
|
+
compacted_item
|
184
|
+
when '@language'
|
185
|
+
map_key = expanded_item[container]
|
186
|
+
value?(expanded_item) ? expanded_item['@value'] : compacted_item
|
187
|
+
when '@type'
|
188
|
+
type_prop = context.compact_iri('@type', vocab: true, quiet: true)
|
189
|
+
map_key, *types = Array(compacted_item[type_prop])
|
190
|
+
map_key = context.compact_iri(map_key, vocab: true, quiet: true)
|
191
|
+
case types.length
|
192
|
+
when 0 then compacted_item.delete(type_prop)
|
193
|
+
when 1 then compacted_item[type_prop] = types.first
|
194
|
+
else compacted_item[type_prop] = types
|
195
|
+
end
|
196
|
+
compacted_item
|
197
|
+
end
|
146
198
|
merge_compacted_value(map_object, map_key, compacted_item)
|
147
199
|
else
|
148
200
|
compacted_item = [compacted_item] if
|
@@ -151,7 +203,7 @@ module JSON::LD
|
|
151
203
|
%w(@set @list).include?(container) ||
|
152
204
|
%w(@list @graph).include?(expanded_property)
|
153
205
|
)
|
154
|
-
merge_compacted_value(
|
206
|
+
merge_compacted_value(nest_result, item_active_property, compacted_item)
|
155
207
|
end
|
156
208
|
end
|
157
209
|
end
|
@@ -163,6 +215,9 @@ module JSON::LD
|
|
163
215
|
#log_debug("compact") {element.class.to_s}
|
164
216
|
element
|
165
217
|
end
|
218
|
+
|
219
|
+
ensure
|
220
|
+
self.context = input_context
|
166
221
|
end
|
167
222
|
end
|
168
223
|
end
|