json-ld 3.1.10 → 3.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +9 -10
- data/VERSION +1 -1
- data/lib/json/ld/api.rb +53 -16
- data/lib/json/ld/context.rb +8 -8
- data/lib/json/ld/expand.rb +2 -2
- data/lib/json/ld/flatten.rb +1 -1
- data/lib/json/ld/format.rb +2 -1
- data/lib/json/ld/reader.rb +2 -2
- data/lib/json/ld/streaming_reader.rb +2 -1
- data/lib/json/ld/to_rdf.rb +9 -8
- data/lib/json/ld/writer.rb +9 -10
- data/lib/json/ld.rb +3 -0
- data/spec/api_spec.rb +67 -19
- data/spec/format_spec.rb +7 -3
- data/spec/frame_spec.rb +25 -1
- data/spec/reader_spec.rb +14 -14
- data/spec/suite_helper.rb +1 -0
- data/spec/test-files/{test-1-compacted.json → test-1-compacted.jsonld} +0 -0
- data/spec/test-files/{test-1-context.json → test-1-context.jsonld} +0 -0
- data/spec/test-files/{test-1-expanded.json → test-1-expanded.jsonld} +0 -0
- data/spec/test-files/{test-1-input.json → test-1-input.jsonld} +0 -0
- data/spec/test-files/{test-2-compacted.json → test-2-compacted.jsonld} +0 -0
- data/spec/test-files/{test-2-context.json → test-2-context.jsonld} +0 -0
- data/spec/test-files/{test-2-expanded.json → test-2-expanded.jsonld} +0 -0
- data/spec/test-files/{test-2-input.json → test-2-input.jsonld} +0 -0
- data/spec/test-files/{test-3-compacted.json → test-3-compacted.jsonld} +0 -0
- data/spec/test-files/{test-3-context.json → test-3-context.jsonld} +0 -0
- data/spec/test-files/{test-3-expanded.json → test-3-expanded.jsonld} +0 -0
- data/spec/test-files/{test-3-input.json → test-3-input.jsonld} +0 -0
- data/spec/test-files/{test-4-compacted.json → test-4-compacted.jsonld} +0 -0
- data/spec/test-files/{test-4-context.json → test-4-context.jsonld} +0 -0
- data/spec/test-files/{test-4-expanded.json → test-4-expanded.jsonld} +0 -0
- data/spec/test-files/{test-4-input.json → test-4-input.jsonld} +0 -0
- data/spec/test-files/{test-5-compacted.json → test-5-compacted.jsonld} +0 -0
- data/spec/test-files/{test-5-context.json → test-5-context.jsonld} +0 -0
- data/spec/test-files/{test-5-expanded.json → test-5-expanded.jsonld} +0 -0
- data/spec/test-files/{test-5-input.json → test-5-input.jsonld} +0 -0
- data/spec/test-files/{test-6-compacted.json → test-6-compacted.jsonld} +0 -0
- data/spec/test-files/{test-6-context.json → test-6-context.jsonld} +0 -0
- data/spec/test-files/{test-6-expanded.json → test-6-expanded.jsonld} +0 -0
- data/spec/test-files/{test-6-input.json → test-6-input.jsonld} +0 -0
- data/spec/test-files/{test-7-compacted.json → test-7-compacted.jsonld} +0 -0
- data/spec/test-files/{test-7-context.json → test-7-context.jsonld} +0 -0
- data/spec/test-files/{test-7-expanded.json → test-7-expanded.jsonld} +0 -0
- data/spec/test-files/{test-7-input.json → test-7-input.jsonld} +0 -0
- data/spec/test-files/{test-8-compacted.json → test-8-compacted.jsonld} +0 -0
- data/spec/test-files/{test-8-context.json → test-8-context.jsonld} +0 -0
- data/spec/test-files/{test-8-expanded.json → test-8-expanded.jsonld} +0 -0
- data/spec/test-files/{test-8-frame.json → test-8-frame.jsonld} +0 -0
- data/spec/test-files/{test-8-framed.json → test-8-framed.jsonld} +0 -0
- data/spec/test-files/{test-8-input.json → test-8-input.jsonld} +0 -0
- data/spec/test-files/{test-9-compacted.json → test-9-compacted.jsonld} +0 -0
- data/spec/test-files/{test-9-context.json → test-9-context.jsonld} +0 -0
- data/spec/test-files/{test-9-expanded.json → test-9-expanded.jsonld} +0 -0
- data/spec/test-files/{test-9-input.json → test-9-input.jsonld} +0 -0
- metadata +110 -111
- data/spec/test-files/test-1-normalized.json +0 -8
- data/spec/test-files/test-2-normalized.json +0 -32
- data/spec/test-files/test-3-normalized.json +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 63c237710b5f32fe8037a11969feaf712a79f68a4d1d568a89ece1a5d1d26ff2
|
4
|
+
data.tar.gz: cac81da94266cac30a7e31e5018477ef55e52b6b1701b048214947f266439236
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 440da082cc1cbabcd69e8cb3d34858c4fe8fd96b116c0d67651d5ce7338d6e787f9d00451ff1f730d08982f0d8697d097f51d09d033ff7f8e290252006f96c78
|
7
|
+
data.tar.gz: 0b877d9d96857964a4913aef1790aa04dc98f83676ec0154c016ad05e7a9dc0a22b1b3bd31ae785cfb4447ac6914291ac56d42f5dc6781fc58c6687ccd4d15cd
|
data/README.md
CHANGED
@@ -32,10 +32,10 @@ This gem also implements an optimized streaming writer used for generating JSON-
|
|
32
32
|
* Each statement written as a separate node in expanded/flattened form.
|
33
33
|
* `RDF List`s are written as separate nodes using `rdf:first` and `rdf:rest` properties.
|
34
34
|
|
35
|
-
The order of triples retrieved from the `RDF::Enumerable` dataset determines the way that JSON-LD node objects are written; for best results, statements should be ordered by _graph name_,
|
35
|
+
The order of triples retrieved from the `RDF::Enumerable` dataset determines the way that JSON-LD node objects are written; for best results, statements should be ordered by _graph name_, _subject_, _predicate_ and _object_.
|
36
36
|
|
37
37
|
### MultiJson parser
|
38
|
-
The [MultiJson](https://rubygems.org/gems/multi_json) gem is used for parsing JSON; this defaults to the native JSON parser, but will use a more performant parser if one is available. A specific parser can be specified by adding the `:adapter` option to any API call. See [MultiJson](https://rubygems.org/gems/multi_json) for more information.
|
38
|
+
The [MultiJson](https://rubygems.org/gems/multi_json) gem is used for parsing and serializing JSON; this defaults to the native JSON parser/serializer, but will use a more performant parser if one is available. A specific parser can be specified by adding the `:adapter` option to any API call. Additionally, a custom serialilzer may be specified by passing the `:serializer` option to {JSON::LD::Writer} or methods of {JSON::LD::API}. See [MultiJson](https://rubygems.org/gems/multi_json) for more information.
|
39
39
|
|
40
40
|
### JSON-LD-star (RDFStar)
|
41
41
|
|
@@ -72,7 +72,7 @@ In the first case, the embedded node is not asserted, and only appears as the su
|
|
72
72
|
|
73
73
|
#### Serializing a Graph containing embedded statements
|
74
74
|
|
75
|
-
require 'json
|
75
|
+
require 'json/ld'
|
76
76
|
statement = RDF::Statement(RDF::URI('bob'), RDF::Vocab::FOAF.age, RDF::Literal(23))
|
77
77
|
graph = RDF::Graph.new << [statement, RDF::URI("ex:certainty"), RDF::Literal(0.9)]
|
78
78
|
graph.dump(:jsonld, validate: false, standard_prefixes: true)
|
@@ -565,7 +565,7 @@ The {JSON::LD::ContentNegotiation#call} method looks for a result which includes
|
|
565
565
|
See [Rack::LinkedData][] to do the same thing with an RDF Graph or Dataset as the source, rather than Ruby objects.
|
566
566
|
|
567
567
|
## Documentation
|
568
|
-
Full documentation available on [RubyDoc](https://
|
568
|
+
Full documentation available on [RubyDoc](https://ruby-rdf.github.io/json-ld/file/README.md)
|
569
569
|
|
570
570
|
## Differences from [JSON-LD API][]
|
571
571
|
The specified JSON-LD API is based on a WebIDL definition implementing [Promises][] intended for use within a browser.
|
@@ -588,9 +588,9 @@ Note, the API method signatures differed in versions before 1.0, in that they al
|
|
588
588
|
* {JSON::LD::Writer}
|
589
589
|
|
590
590
|
## Dependencies
|
591
|
-
* [Ruby](https://ruby-lang.org/) (>= 2.
|
592
|
-
* [RDF.rb](https://rubygems.org/gems/rdf) (~> 3.
|
593
|
-
* [JSON](https://rubygems.org/gems/json) (>= 2.
|
591
|
+
* [Ruby](https://ruby-lang.org/) (>= 2.6)
|
592
|
+
* [RDF.rb](https://rubygems.org/gems/rdf) (~> 3.2)
|
593
|
+
* [JSON](https://rubygems.org/gems/json) (>= 2.6)
|
594
594
|
|
595
595
|
## Installation
|
596
596
|
The recommended installation method is via [RubyGems](https://rubygems.org/).
|
@@ -624,8 +624,7 @@ To get a local working copy of the development repository, do:
|
|
624
624
|
which you will be asked to agree to on the first commit to a repo within the organization.
|
625
625
|
Note that the agreement applies to all repos in the [Ruby RDF](https://github.com/ruby-rdf/) organization.
|
626
626
|
|
627
|
-
License
|
628
|
-
-------
|
627
|
+
## License
|
629
628
|
|
630
629
|
This is free and unencumbered public domain software. For more information,
|
631
630
|
see <https://unlicense.org/> or the accompanying {file:UNLICENSE} file.
|
@@ -641,7 +640,7 @@ see <https://unlicense.org/> or the accompanying {file:UNLICENSE} file.
|
|
641
640
|
[Backports]: https://rubygems.org/gems/backports
|
642
641
|
[JSON-LD]: https://www.w3.org/TR/json-ld11/ "JSON-LD 1.1"
|
643
642
|
[JSON-LD API]: https://www.w3.org/TR/json-ld11-api/ "JSON-LD 1.1 Processing Algorithms and API"
|
644
|
-
[JSON-LD Framing]: https://www.w3.org/TR/json-ld11-framing/ "JSON-LD
|
643
|
+
[JSON-LD Framing]: https://www.w3.org/TR/json-ld11-framing/ "JSON-LD 1.1 Framing"
|
645
644
|
[Promises]: https://dom.spec.whatwg.org/#promises
|
646
645
|
[jsonlint]: https://rubygems.org/gems/jsonlint
|
647
646
|
[Sinatra]: https://www.sinatrarb.com/
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.
|
1
|
+
3.2.2
|
data/lib/json/ld/api.rb
CHANGED
@@ -126,7 +126,8 @@ module JSON::LD
|
|
126
126
|
|
127
127
|
case remote_doc.document
|
128
128
|
when String
|
129
|
-
|
129
|
+
mj_opts = options.keep_if {|k,v| k != :adapter || MUTLI_JSON_ADAPTERS.include?(v)}
|
130
|
+
MultiJson.load(remote_doc.document, **mj_opts)
|
130
131
|
else
|
131
132
|
# Already parsed
|
132
133
|
remote_doc.document
|
@@ -155,6 +156,9 @@ module JSON::LD
|
|
155
156
|
#
|
156
157
|
# @param [String, #read, Hash, Array] input
|
157
158
|
# The JSON-LD object to copy and perform the expansion upon.
|
159
|
+
# @param [Proc] serializer (nil)
|
160
|
+
# A Serializer method used for generating the JSON serialization of the result. If absent, the internal Ruby objects are returned, which can be transformed to JSON externally via `#to_json`.
|
161
|
+
# See {JSON::LD::API.serializer}.
|
158
162
|
# @param [Hash{Symbol => Object}] options
|
159
163
|
# @option options (see #initialize)
|
160
164
|
# @raise [JsonLdError]
|
@@ -167,7 +171,7 @@ module JSON::LD
|
|
167
171
|
# @return [Object, Array<Hash>]
|
168
172
|
# If a block is given, the result of evaluating the block is returned, otherwise, the expanded JSON-LD document
|
169
173
|
# @see https://www.w3.org/TR/json-ld11-api/#expansion-algorithm
|
170
|
-
def self.expand(input, framing: false, **options, &block)
|
174
|
+
def self.expand(input, framing: false, serializer: nil, **options, &block)
|
171
175
|
result = doc_base = nil
|
172
176
|
API.new(input, options[:expandContext], **options) do
|
173
177
|
result = self.expand(self.value, nil, self.context,
|
@@ -180,6 +184,7 @@ module JSON::LD
|
|
180
184
|
|
181
185
|
# Finally, if element is a JSON object, it is wrapped into an array.
|
182
186
|
result = [result].compact unless result.is_a?(Array)
|
187
|
+
result = serializer.call(result, **options) if serializer
|
183
188
|
|
184
189
|
if block_given?
|
185
190
|
case block.arity
|
@@ -204,6 +209,9 @@ module JSON::LD
|
|
204
209
|
# The JSON-LD object to copy and perform the compaction upon.
|
205
210
|
# @param [String, #read, Hash, Array, JSON::LD::Context] context
|
206
211
|
# The base context to use when compacting the input.
|
212
|
+
# @param [Proc] serializer (nil)
|
213
|
+
# A Serializer instance used for generating the JSON serialization of the result. If absent, the internal Ruby objects are returned, which can be transformed to JSON externally via `#to_json`.
|
214
|
+
# See {JSON::LD::API.serializer}.
|
207
215
|
# @param [Boolean] expanded (false) Input is already expanded
|
208
216
|
# @param [Hash{Symbol => Object}] options
|
209
217
|
# @option options (see #initialize)
|
@@ -215,7 +223,7 @@ module JSON::LD
|
|
215
223
|
# If a block is given, the result of evaluating the block is returned, otherwise, the compacted JSON-LD document
|
216
224
|
# @raise [JsonLdError]
|
217
225
|
# @see https://www.w3.org/TR/json-ld11-api/#compaction-algorithm
|
218
|
-
def self.compact(input, context, expanded: false, **options)
|
226
|
+
def self.compact(input, context, expanded: false, serializer: nil, **options)
|
219
227
|
result = nil
|
220
228
|
options = {compactToRelative: true}.merge(options)
|
221
229
|
|
@@ -238,6 +246,7 @@ module JSON::LD
|
|
238
246
|
end
|
239
247
|
result = ctx.merge(result) unless ctx.fetch('@context', {}).empty?
|
240
248
|
end
|
249
|
+
result = serializer.call(result, **options) if serializer
|
241
250
|
block_given? ? yield(result) : result
|
242
251
|
end
|
243
252
|
|
@@ -251,6 +260,9 @@ module JSON::LD
|
|
251
260
|
# @param [String, #read, Hash, Array, JSON::LD::EvaluationContext] context
|
252
261
|
# An optional external context to use additionally to the context embedded in input when expanding the input.
|
253
262
|
# @param [Boolean] expanded (false) Input is already expanded
|
263
|
+
# @param [Proc] serializer (nil)
|
264
|
+
# A Serializer instance used for generating the JSON serialization of the result. If absent, the internal Ruby objects are returned, which can be transformed to JSON externally via `#to_json`.
|
265
|
+
# See {JSON::LD::API.serializer}.
|
254
266
|
# @param [Hash{Symbol => Object}] options
|
255
267
|
# @option options (see #initialize)
|
256
268
|
# @option options [Boolean] :createAnnotations
|
@@ -262,7 +274,7 @@ module JSON::LD
|
|
262
274
|
# @return [Object, Hash]
|
263
275
|
# If a block is given, the result of evaluating the block is returned, otherwise, the flattened JSON-LD document
|
264
276
|
# @see https://www.w3.org/TR/json-ld11-api/#framing-algorithm
|
265
|
-
def self.flatten(input, context, expanded: false, **options)
|
277
|
+
def self.flatten(input, context, expanded: false, serializer: nil, **options)
|
266
278
|
flattened = []
|
267
279
|
options = {
|
268
280
|
compactToRelative: true,
|
@@ -318,6 +330,7 @@ module JSON::LD
|
|
318
330
|
end
|
319
331
|
end
|
320
332
|
|
333
|
+
flattened = serializer.call(flattened, **options) if serializer
|
321
334
|
block_given? ? yield(flattened) : flattened
|
322
335
|
end
|
323
336
|
|
@@ -350,7 +363,7 @@ module JSON::LD
|
|
350
363
|
# If a block is given, the result of evaluating the block is returned, otherwise, the framed JSON-LD document
|
351
364
|
# @raise [InvalidFrame]
|
352
365
|
# @see https://www.w3.org/TR/json-ld11-api/#framing-algorithm
|
353
|
-
def self.frame(input, frame, expanded: false, **options)
|
366
|
+
def self.frame(input, frame, expanded: false, serializer: nil, **options)
|
354
367
|
result = nil
|
355
368
|
options = {
|
356
369
|
base: (RDF::URI(input) if input.is_a?(String)),
|
@@ -379,7 +392,8 @@ module JSON::LD
|
|
379
392
|
requestProfile: 'http://www.w3.org/ns/json-ld#frame',
|
380
393
|
**options)
|
381
394
|
if remote_doc.document.is_a?(String)
|
382
|
-
|
395
|
+
mj_opts = options.keep_if {|k,v| k != :adapter || MUTLI_JSON_ADAPTERS.include?(v)}
|
396
|
+
MultiJson.load(remote_doc.document, **mj_opts)
|
383
397
|
else
|
384
398
|
remote_doc.document
|
385
399
|
end
|
@@ -467,6 +481,7 @@ module JSON::LD
|
|
467
481
|
result
|
468
482
|
end
|
469
483
|
|
484
|
+
result = serializer.call(result, **options) if serializer
|
470
485
|
block_given? ? yield(result) : result
|
471
486
|
end
|
472
487
|
|
@@ -528,18 +543,21 @@ module JSON::LD
|
|
528
543
|
# The resulting `Array` is either returned or yielded, if a block is given.
|
529
544
|
#
|
530
545
|
# @param [RDF::Enumerable] input
|
546
|
+
# @param [Boolean] useRdfType (false)
|
547
|
+
# If set to `true`, the JSON-LD processor will treat `rdf:type` like a normal property instead of using `@type`.
|
548
|
+
# @param [Boolean] useNativeTypes (false) use native representations
|
549
|
+
# @param [Proc] serializer (nil)
|
550
|
+
# A Serializer instance used for generating the JSON serialization of the result. If absent, the internal Ruby objects are returned, which can be transformed to JSON externally via `#to_json`.
|
551
|
+
# See {JSON::LD::API.serializer}.
|
531
552
|
# @param [Hash{Symbol => Object}] options
|
532
553
|
# @option options (see #initialize)
|
533
|
-
# @option options [Boolean] :useRdfType (false)
|
534
|
-
# If set to `true`, the JSON-LD processor will treat `rdf:type` like a normal property instead of using `@type`.
|
535
|
-
# @option options [Boolean] :useNativeTypes (false) use native representations
|
536
554
|
# @yield jsonld
|
537
555
|
# @yieldparam [Hash] jsonld
|
538
556
|
# The JSON-LD document in expanded form
|
539
557
|
# @yieldreturn [Object] returned object
|
540
558
|
# @return [Object, Hash]
|
541
559
|
# If a block is given, the result of evaluating the block is returned, otherwise, the expanded JSON-LD document
|
542
|
-
def self.fromRdf(input, useRdfType: false, useNativeTypes: false, **options, &block)
|
560
|
+
def self.fromRdf(input, useRdfType: false, useNativeTypes: false, serializer: nil, **options, &block)
|
543
561
|
result = nil
|
544
562
|
|
545
563
|
API.new(nil, nil, **options) do
|
@@ -548,6 +566,7 @@ module JSON::LD
|
|
548
566
|
useNativeTypes: useNativeTypes)
|
549
567
|
end
|
550
568
|
|
569
|
+
result = serializer.call(result, **options) if serializer
|
551
570
|
block_given? ? yield(result) : result
|
552
571
|
end
|
553
572
|
|
@@ -648,7 +667,8 @@ module JSON::LD
|
|
648
667
|
end
|
649
668
|
else
|
650
669
|
validate_input(remote_doc.document, url: remote_doc.documentUrl) if validate
|
651
|
-
|
670
|
+
mj_opts = options.keep_if {|k,v| k != :adapter || MUTLI_JSON_ADAPTERS.include?(v)}
|
671
|
+
MultiJson.load(remote_doc.document, **mj_opts)
|
652
672
|
end
|
653
673
|
end
|
654
674
|
|
@@ -682,8 +702,8 @@ module JSON::LD
|
|
682
702
|
base_uri ||= url.base_uri if url.respond_to?(:base_uri)
|
683
703
|
content_type = options[:content_type]
|
684
704
|
content_type ||= url.content_type if url.respond_to?(:content_type)
|
685
|
-
context_url = if url.respond_to?(:links) && url.links
|
686
|
-
(content_type == '
|
705
|
+
context_url = if url.respond_to?(:links) && url.links &&
|
706
|
+
(content_type == 'application/json' || content_type.match?(%r(application/(^ld)+json)))
|
687
707
|
link = url.links.find_link(LINK_REL_CONTEXT)
|
688
708
|
link.href if link
|
689
709
|
end
|
@@ -759,7 +779,8 @@ module JSON::LD
|
|
759
779
|
raise JSON::LD::JsonLdError::LoadingDocumentFailed, "Script tag has type=#{element.attributes['type']}" unless element.attributes['type'].to_s.start_with?('application/ld+json')
|
760
780
|
content = element.inner_html
|
761
781
|
validate_input(content, url: url) if options[:validate]
|
762
|
-
|
782
|
+
mj_opts = options.keep_if {|k,v| k != :adapter || MUTLI_JSON_ADAPTERS.include?(v)}
|
783
|
+
MultiJson.load(content, **mj_opts)
|
763
784
|
elsif extractAllScripts
|
764
785
|
res = []
|
765
786
|
elements = if profile
|
@@ -773,7 +794,8 @@ module JSON::LD
|
|
773
794
|
elements.each do |element|
|
774
795
|
content = element.inner_html
|
775
796
|
validate_input(content, url: url) if options[:validate]
|
776
|
-
|
797
|
+
mj_opts = options.keep_if {|k,v| k != :adapter || MUTLI_JSON_ADAPTERS.include?(v)}
|
798
|
+
r = MultiJson.load(content, **mj_opts)
|
777
799
|
if r.is_a?(Hash)
|
778
800
|
res << r
|
779
801
|
elsif r.is_a?(Array)
|
@@ -788,12 +810,27 @@ module JSON::LD
|
|
788
810
|
raise JSON::LD::JsonLdError::LoadingDocumentFailed, "No script tag found" unless element
|
789
811
|
content = element.inner_html
|
790
812
|
validate_input(content, url: url) if options[:validate]
|
791
|
-
|
813
|
+
mj_opts = options.keep_if {|k,v| k != :adapter || MUTLI_JSON_ADAPTERS.include?(v)}
|
814
|
+
MultiJson.load(content, **mj_opts)
|
792
815
|
end
|
793
816
|
rescue MultiJson::ParseError => e
|
794
817
|
raise JSON::LD::JsonLdError::InvalidScriptElement, e.message
|
795
818
|
end
|
796
819
|
|
820
|
+
##
|
821
|
+
# The default serializer for serialzing Ruby Objects to JSON.
|
822
|
+
#
|
823
|
+
# Defaults to `MultiJson.dump`
|
824
|
+
#
|
825
|
+
# @param [Object] object
|
826
|
+
# @param [Array<Object>] args
|
827
|
+
# other arguments that may be passed for some specific implementation.
|
828
|
+
# @param [Hash<Symbol, Object>] options
|
829
|
+
# options passed from the invoking context.
|
830
|
+
def self.serializer(object, *args, **options)
|
831
|
+
MultiJson.dump(object, JSON_STATE)
|
832
|
+
end
|
833
|
+
|
797
834
|
##
|
798
835
|
# Validate JSON using JsonLint, if loaded
|
799
836
|
private
|
data/lib/json/ld/context.rb
CHANGED
@@ -5,13 +5,6 @@ require 'bigdecimal'
|
|
5
5
|
require 'set'
|
6
6
|
require 'rdf/util/cache'
|
7
7
|
|
8
|
-
begin
|
9
|
-
# Attempt to load this to avoid unnecessary context fetches
|
10
|
-
require 'json-ld-preloaded'
|
11
|
-
rescue LoadError
|
12
|
-
# Silently allow this to fail
|
13
|
-
end
|
14
|
-
|
15
8
|
module JSON::LD
|
16
9
|
class Context
|
17
10
|
include Utils
|
@@ -50,6 +43,13 @@ module JSON::LD
|
|
50
43
|
end
|
51
44
|
end
|
52
45
|
|
46
|
+
begin
|
47
|
+
# Attempt to load this to avoid unnecessary context fetches
|
48
|
+
require 'json/ld/preloaded'
|
49
|
+
rescue LoadError
|
50
|
+
# Silently allow this to fail
|
51
|
+
end
|
52
|
+
|
53
53
|
# The base.
|
54
54
|
#
|
55
55
|
# @return [RDF::URI] Current base IRI, used for expanding relative IRIs.
|
@@ -1688,7 +1688,7 @@ module JSON::LD
|
|
1688
1688
|
ec.default_direction = that.default_direction
|
1689
1689
|
ec.default_language = that.default_language
|
1690
1690
|
ec.previous_context = that.previous_context
|
1691
|
-
ec.processingMode = that.processingMode if that.instance_variable_get(:@
|
1691
|
+
ec.processingMode = that.processingMode if that.instance_variable_get(:@processingMode)
|
1692
1692
|
ec.vocab = that.vocab if that.vocab
|
1693
1693
|
|
1694
1694
|
ec.instance_eval do
|
data/lib/json/ld/expand.rb
CHANGED
@@ -88,7 +88,7 @@ module JSON::LD
|
|
88
88
|
|
89
89
|
# 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.
|
90
90
|
if input.key?('@context')
|
91
|
-
context = context.parse(input
|
91
|
+
context = context.parse(input['@context'], base: @options[:base])
|
92
92
|
log_debug("expand", depth: log_depth.to_i) {"context: #{context.inspect}"}
|
93
93
|
end
|
94
94
|
|
@@ -99,7 +99,7 @@ module JSON::LD
|
|
99
99
|
|
100
100
|
# See if keys mapping to @type have terms with a local context
|
101
101
|
type_key = nil
|
102
|
-
input.keys.sort.
|
102
|
+
(input.keys - %w(@context)).sort.
|
103
103
|
select {|k| context.expand_iri(k, vocab: true, base: @options[:base]) == '@type'}.
|
104
104
|
each do |tk|
|
105
105
|
|
data/lib/json/ld/flatten.rb
CHANGED
@@ -202,7 +202,7 @@ module JSON::LD
|
|
202
202
|
# * Deserialize the key into a map, and re-serialize the value of `@id`.
|
203
203
|
# * If the map contains an entry with that value (after re-canonicalizing, as appropriate), and the associated antry has a item which matches the non-`@id` item from the map, the node is used to create an `@annotation` entry within that value.
|
204
204
|
#
|
205
|
-
# @param [Hash{String => Hash}]
|
205
|
+
# @param [Hash{String => Hash}] node_map
|
206
206
|
# @return [Hash{String => Hash}]
|
207
207
|
def create_annotations(node_map)
|
208
208
|
node_map.keys.
|
data/lib/json/ld/format.rb
CHANGED
@@ -23,7 +23,8 @@ module JSON::LD
|
|
23
23
|
class Format < RDF::Format
|
24
24
|
content_type 'application/ld+json',
|
25
25
|
extension: :jsonld,
|
26
|
-
alias: 'application/x-ld+json'
|
26
|
+
alias: 'application/x-ld+json',
|
27
|
+
uri: 'http://www.w3.org/ns/formats/JSON-LD'
|
27
28
|
content_encoding 'utf-8'
|
28
29
|
|
29
30
|
reader { JSON::LD::Reader }
|
data/lib/json/ld/reader.rb
CHANGED
@@ -12,7 +12,7 @@ module JSON::LD
|
|
12
12
|
|
13
13
|
##
|
14
14
|
# JSON-LD Reader options
|
15
|
-
# @see
|
15
|
+
# @see https://ruby-rdf.github.io/rdf/RDF/Reader#options-class_method
|
16
16
|
def self.options
|
17
17
|
super + [
|
18
18
|
RDF::CLI::Option.new(
|
@@ -57,7 +57,7 @@ module JSON::LD
|
|
57
57
|
end
|
58
58
|
|
59
59
|
##
|
60
|
-
# Initializes the
|
60
|
+
# Initializes the JSON-LD reader instance.
|
61
61
|
#
|
62
62
|
# @param [IO, File, String] input
|
63
63
|
# @param [Hash{Symbol => Object}] options
|
@@ -26,7 +26,8 @@ module JSON::LD
|
|
26
26
|
unique_bnodes, rename_bnodes = @options[:unique_bnodes], @options.fetch(:rename_bnodes, true)
|
27
27
|
# FIXME: document loader doesn't stream
|
28
28
|
@base = RDF::URI(@options[:base] || base_uri)
|
29
|
-
|
29
|
+
mj_opts = @options.keep_if {|k,v| k != :adapter || MUTLI_JSON_ADAPTERS.include?(v)}
|
30
|
+
value = MultiJson.load(@doc, mj_opts)
|
30
31
|
context_ref = @options[:expandContext]
|
31
32
|
#context_ref = @options.fetch(:expandContext, remote_doc.contextUrl)
|
32
33
|
context = Context.parse(context_ref, **@options)
|
data/lib/json/ld/to_rdf.rb
CHANGED
@@ -11,10 +11,11 @@ module JSON::LD
|
|
11
11
|
##
|
12
12
|
# @param [Hash{String => Object}] item
|
13
13
|
# @param [RDF::Resource] graph_name
|
14
|
+
# @param [Boolean] quoted emitted triples are quoted triples.
|
14
15
|
# @yield statement
|
15
16
|
# @yieldparam [RDF::Statement] statement
|
16
17
|
# @return RDF::Resource the subject of this item
|
17
|
-
def item_to_rdf(item, graph_name: nil, &block)
|
18
|
+
def item_to_rdf(item, graph_name: nil, quoted: false, &block)
|
18
19
|
# Just return value object as Term
|
19
20
|
return unless item
|
20
21
|
|
@@ -82,9 +83,9 @@ module JSON::LD
|
|
82
83
|
when nil then node
|
83
84
|
when String then as_resource(item['@id'])
|
84
85
|
when Object
|
85
|
-
# Embedded statement
|
86
|
+
# Embedded/quoted statement
|
86
87
|
# (No error checking, as this is done in expansion)
|
87
|
-
to_enum(:item_to_rdf, item['@id']).to_a.first
|
88
|
+
to_enum(:item_to_rdf, item['@id'], quoted: true).to_a.first
|
88
89
|
end
|
89
90
|
|
90
91
|
#log_debug("item_to_rdf") {"subject: #{subject.to_ntriples rescue 'malformed rdf'}"}
|
@@ -95,12 +96,12 @@ module JSON::LD
|
|
95
96
|
values.each do |v|
|
96
97
|
object = as_resource(v)
|
97
98
|
#log_debug("item_to_rdf") {"type: #{object.to_ntriples rescue 'malformed rdf'}"}
|
98
|
-
yield RDF::Statement(subject, RDF.type, object, graph_name: graph_name)
|
99
|
+
yield RDF::Statement(subject, RDF.type, object, graph_name: graph_name, quoted: quoted)
|
99
100
|
end
|
100
101
|
when '@graph'
|
101
102
|
values = [values].compact unless values.is_a?(Array)
|
102
103
|
values.each do |nd|
|
103
|
-
item_to_rdf(nd, graph_name: subject, &block)
|
104
|
+
item_to_rdf(nd, graph_name: subject, quoted: quoted, &block)
|
104
105
|
end
|
105
106
|
when '@reverse'
|
106
107
|
raise "Huh?" unless values.is_a?(Hash)
|
@@ -113,7 +114,7 @@ module JSON::LD
|
|
113
114
|
object = item_to_rdf(v, graph_name: graph_name, &block)
|
114
115
|
#log_debug("item_to_rdf") {"subject: #{object.to_ntriples rescue 'malformed rdf'}"}
|
115
116
|
# yield subject, prediate, and literal to results.
|
116
|
-
yield RDF::Statement(object, predicate, subject, graph_name: graph_name)
|
117
|
+
yield RDF::Statement(object, predicate, subject, graph_name: graph_name, quoted: quoted)
|
117
118
|
end
|
118
119
|
end
|
119
120
|
when '@included'
|
@@ -136,13 +137,13 @@ module JSON::LD
|
|
136
137
|
object = parse_list(v['@list'], graph_name: graph_name, &block)
|
137
138
|
|
138
139
|
# Append a triple composed of subject, prediate, and object to results and add all triples from list_results to results.
|
139
|
-
yield RDF::Statement(subject, predicate, object, graph_name: graph_name)
|
140
|
+
yield RDF::Statement(subject, predicate, object, graph_name: graph_name, quoted: quoted)
|
140
141
|
else
|
141
142
|
# Otherwise, item is a value object or a node definition. Generate object as the result of the Object Converstion algorithm passing item.
|
142
143
|
object = item_to_rdf(v, graph_name: graph_name, &block)
|
143
144
|
#log_debug("item_to_rdf") {"object: #{object.to_ntriples rescue 'malformed rdf'}"}
|
144
145
|
# yield subject, prediate, and literal to results.
|
145
|
-
yield RDF::Statement(subject, predicate, object, graph_name: graph_name)
|
146
|
+
yield RDF::Statement(subject, predicate, object, graph_name: graph_name, quoted: quoted)
|
146
147
|
end
|
147
148
|
end
|
148
149
|
end
|
data/lib/json/ld/writer.rb
CHANGED
@@ -71,7 +71,7 @@ module JSON::LD
|
|
71
71
|
|
72
72
|
##
|
73
73
|
# JSON-LD Writer options
|
74
|
-
# @see
|
74
|
+
# @see https://ruby-rdf.github.io/rdf/RDF/Writer#options-class_method
|
75
75
|
def self.options
|
76
76
|
super + [
|
77
77
|
RDF::CLI::Option.new(
|
@@ -186,10 +186,6 @@ module JSON::LD
|
|
186
186
|
# @return [Boolean]
|
187
187
|
# @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1
|
188
188
|
def accept?(accept_params)
|
189
|
-
# Profiles that aren't specific IANA relations represent the URL
|
190
|
-
# of a context or frame that may be subject to black- or white-listing
|
191
|
-
profile = accept_params[:profile].to_s.split(/\s+/)
|
192
|
-
|
193
189
|
if block_given?
|
194
190
|
yield(accept_params)
|
195
191
|
else
|
@@ -229,6 +225,8 @@ module JSON::LD
|
|
229
225
|
# frame to use when serializing.
|
230
226
|
# @option options [Boolean] :unique_bnodes (false)
|
231
227
|
# Use unique bnode identifiers, defaults to using the identifier which the node was originall initialized with (if any).
|
228
|
+
# @option options [Proc] serializer (JSON::LD::API.serializer)
|
229
|
+
# A Serializer method used for generating the JSON serialization of the result.
|
232
230
|
# @option options [Boolean] :stream (false)
|
233
231
|
# Do not attempt to optimize graph presentation, suitable for streaming large graphs.
|
234
232
|
# @yield [writer] `self`
|
@@ -239,6 +237,7 @@ module JSON::LD
|
|
239
237
|
def initialize(output = $stdout, **options, &block)
|
240
238
|
options[:base_uri] ||= options[:base] if options.key?(:base)
|
241
239
|
options[:base] ||= options[:base_uri] if options.key?(:base_uri)
|
240
|
+
@serializer = options.fetch(:serializer, JSON::LD::API.method(:serializer))
|
242
241
|
super do
|
243
242
|
@repo = RDF::Repository.new
|
244
243
|
|
@@ -300,7 +299,7 @@ module JSON::LD
|
|
300
299
|
else
|
301
300
|
|
302
301
|
log_debug("writer") { "serialize #{@repo.count} statements, #{@options.inspect}"}
|
303
|
-
result = API.fromRdf(@repo, **@options)
|
302
|
+
result = API.fromRdf(@repo, **@options.merge(serializer: nil))
|
304
303
|
|
305
304
|
# Some options may be indicated from accept parameters
|
306
305
|
profile = @options.fetch(:accept_params, {}).fetch(:profile, "").split(' ')
|
@@ -322,20 +321,20 @@ module JSON::LD
|
|
322
321
|
|
323
322
|
# Rename BNodes to uniquify them, if necessary
|
324
323
|
if options[:unique_bnodes]
|
325
|
-
result = API.flatten(result, context, **@options)
|
324
|
+
result = API.flatten(result, context, **@options.merge(serializer: nil))
|
326
325
|
end
|
327
326
|
|
328
327
|
if frame = @options[:frame]
|
329
328
|
# Perform framing, if given a frame
|
330
329
|
log_debug("writer") { "frame result"}
|
331
|
-
result = API.frame(result, frame, **@options)
|
330
|
+
result = API.frame(result, frame, **@options.merge(serializer: nil))
|
332
331
|
elsif context
|
333
332
|
# Perform compaction, if we have a context
|
334
333
|
log_debug("writer") { "compact result"}
|
335
|
-
result = API.compact(result, context, **@options)
|
334
|
+
result = API.compact(result, context, **@options.merge(serializer: nil))
|
336
335
|
end
|
337
336
|
|
338
|
-
@output.write(
|
337
|
+
@output.write(@serializer.call(result, **@options))
|
339
338
|
end
|
340
339
|
|
341
340
|
super
|
data/lib/json/ld.rb
CHANGED
@@ -46,6 +46,9 @@ module JSON
|
|
46
46
|
# Default context when compacting without one being specified
|
47
47
|
DEFAULT_CONTEXT = "http://schema.org"
|
48
48
|
|
49
|
+
# Acceptable MultiJson adapters
|
50
|
+
MUTLI_JSON_ADAPTERS = %i(oj json_gem json_pure ok_json yajl nsjsonseerialization)
|
51
|
+
|
49
52
|
KEYWORDS = Set.new(%w(
|
50
53
|
@annotation
|
51
54
|
@base
|
data/spec/api_spec.rb
CHANGED
@@ -48,30 +48,78 @@ describe JSON::LD::API do
|
|
48
48
|
context "with MultiJson adapter #{adapter.inspect}" do
|
49
49
|
Dir.glob(File.expand_path(File.join(File.dirname(__FILE__), 'test-files/*-input.*'))) do |filename|
|
50
50
|
test = File.basename(filename).sub(/-input\..*$/, '')
|
51
|
-
frame = filename.sub(/-input\..*$/, '-frame.
|
52
|
-
framed = filename.sub(/-input\..*$/, '-framed.
|
53
|
-
compacted = filename.sub(/-input\..*$/, '-compacted.
|
54
|
-
context = filename.sub(/-input\..*$/, '-context.
|
55
|
-
expanded = filename.sub(/-input\..*$/, '-expanded.
|
51
|
+
frame = filename.sub(/-input\..*$/, '-frame.jsonld')
|
52
|
+
framed = filename.sub(/-input\..*$/, '-framed.jsonld')
|
53
|
+
compacted = filename.sub(/-input\..*$/, '-compacted.jsonld')
|
54
|
+
context = filename.sub(/-input\..*$/, '-context.jsonld')
|
55
|
+
expanded = filename.sub(/-input\..*$/, '-expanded.jsonld')
|
56
56
|
ttl = filename.sub(/-input\..*$/, '-rdf.ttl')
|
57
57
|
|
58
58
|
context test, skip: ("Not supported in JRuby" if RUBY_ENGINE == "jruby" && %w(oj yajl).include?(adapter.to_s)) do
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
59
|
+
around do |example|
|
60
|
+
@file = File.open(filename)
|
61
|
+
case filename
|
62
|
+
when /.jsonld$/
|
63
|
+
@file.define_singleton_method(:content_type) {'application/ld+json'}
|
64
|
+
end
|
65
|
+
if context
|
66
|
+
@ctx_io = File.open(context)
|
67
|
+
case context
|
68
|
+
when /.jsonld$/
|
69
|
+
@ctx_io.define_singleton_method(:content_type) {'application/ld+json'}
|
70
|
+
end
|
71
|
+
end
|
72
|
+
example.run
|
73
|
+
@file.close
|
74
|
+
@ctx_io.close if @ctx_io
|
75
|
+
end
|
76
|
+
|
77
|
+
if File.exist?(expanded)
|
78
|
+
it "expands" do
|
79
|
+
options = {logger: logger, adapter: adapter}
|
80
|
+
options[:expandContext] = @ctx_io if context
|
81
|
+
jld = described_class.expand(@file, **options)
|
82
|
+
expect(jld).to produce_jsonld(JSON.parse(File.read(expanded)), logger)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "expands with serializer" do
|
86
|
+
options = {logger: logger, adapter: adapter}
|
87
|
+
options[:expandContext] = @ctx_io if context
|
88
|
+
jld = described_class.expand(@file, serializer: JSON::LD::API.method(:serializer), **options)
|
89
|
+
expect(jld).to be_a(String)
|
90
|
+
expect(JSON.load(jld)).to produce_jsonld(JSON.parse(File.read(expanded)), logger)
|
91
|
+
end
|
92
|
+
end
|
65
93
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
94
|
+
if File.exist?(compacted) && File.exist?(context)
|
95
|
+
it "compacts" do
|
96
|
+
jld = described_class.compact(@file, @ctx_io, adapter: adapter, logger: logger)
|
97
|
+
expect(jld).to produce_jsonld(JSON.parse(File.read(compacted)), logger)
|
98
|
+
end
|
99
|
+
|
100
|
+
it "compacts with serializer" do
|
101
|
+
jld = described_class.compact(@file, @ctx_io, serializer: JSON::LD::API.method(:serializer), adapter: adapter, logger: logger)
|
102
|
+
expect(jld).to be_a(String)
|
103
|
+
expect(JSON.load(jld)).to produce_jsonld(JSON.parse(File.read(compacted)), logger)
|
104
|
+
end
|
105
|
+
end
|
70
106
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
107
|
+
if File.exist?(framed) && File.exist?(frame)
|
108
|
+
it "frames" do
|
109
|
+
File.open(frame) do |frame_io|
|
110
|
+
jld = described_class.frame(@file, frame_io, adapter: adapter, logger: logger)
|
111
|
+
expect(jld).to produce_jsonld(JSON.parse(File.read(framed)), logger)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
it "frames with serializer" do
|
116
|
+
File.open(frame) do |frame_io|
|
117
|
+
jld = described_class.frame(@file, frame_io, serializer: JSON::LD::API.method(:serializer), adapter: adapter, logger: logger)
|
118
|
+
expect(jld).to be_a(String)
|
119
|
+
expect(JSON.load(jld)).to produce_jsonld(JSON.parse(File.read(framed)), logger)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
75
123
|
|
76
124
|
it "toRdf" do
|
77
125
|
expect(RDF::Repository.load(filename, format: :jsonld, adapter: adapter, logger: logger)).to be_equivalent_graph(RDF::Repository.load(ttl), logger: logger)
|