json-ld 0.9.1 → 1.0.0
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.
- data/{README.markdown → README.md} +15 -3
- data/VERSION +1 -1
- data/lib/json/ld.rb +50 -87
- data/lib/json/ld/api.rb +85 -96
- data/lib/json/ld/compact.rb +103 -170
- data/lib/json/ld/context.rb +1137 -0
- data/lib/json/ld/expand.rb +212 -171
- data/lib/json/ld/extensions.rb +17 -1
- data/lib/json/ld/flatten.rb +145 -78
- data/lib/json/ld/frame.rb +1 -1
- data/lib/json/ld/from_rdf.rb +73 -103
- data/lib/json/ld/reader.rb +3 -1
- data/lib/json/ld/resource.rb +3 -3
- data/lib/json/ld/to_rdf.rb +98 -109
- data/lib/json/ld/utils.rb +54 -4
- data/lib/json/ld/writer.rb +5 -5
- data/spec/api_spec.rb +3 -28
- data/spec/compact_spec.rb +76 -113
- data/spec/{evaluation_context_spec.rb → context_spec.rb} +307 -563
- data/spec/expand_spec.rb +163 -187
- data/spec/flatten_spec.rb +119 -114
- data/spec/frame_spec.rb +5 -5
- data/spec/from_rdf_spec.rb +44 -24
- data/spec/suite_compact_spec.rb +11 -8
- data/spec/suite_error_expand_spec.rb +23 -0
- data/spec/suite_expand_spec.rb +3 -7
- data/spec/suite_flatten_spec.rb +3 -3
- data/spec/suite_frame_spec.rb +6 -6
- data/spec/suite_from_rdf_spec.rb +3 -3
- data/spec/suite_helper.rb +13 -6
- data/spec/suite_to_rdf_spec.rb +16 -10
- data/spec/test-files/test-1-rdf.ttl +4 -3
- data/spec/test-files/test-3-rdf.ttl +2 -1
- data/spec/test-files/test-4-compacted.json +1 -1
- data/spec/test-files/test-5-rdf.ttl +3 -2
- data/spec/test-files/test-6-rdf.ttl +3 -2
- data/spec/test-files/test-7-compacted.json +3 -3
- data/spec/test-files/test-7-expanded.json +3 -3
- data/spec/test-files/test-7-rdf.ttl +7 -6
- data/spec/test-files/test-9-compacted.json +1 -1
- data/spec/to_rdf_spec.rb +67 -75
- data/spec/writer_spec.rb +2 -0
- metadata +36 -24
- checksums.yaml +0 -15
- data/lib/json/ld/evaluation_context.rb +0 -984
@@ -1,8 +1,10 @@
|
|
1
1
|
# JSON-LD reader/writer
|
2
2
|
|
3
|
-
[](http://travis-ci.org/gkellogg/json-ld)
|
4
3
|
[JSON-LD][] reader/writer for [RDF.rb][RDF.rb] and fully conforming [JSON-LD][] processor.
|
5
4
|
|
5
|
+
[](http://badge.fury.io/rb/json-ld)
|
6
|
+
[](http://travis-ci.org/gkellogg/json-ld)
|
7
|
+
|
6
8
|
## Features
|
7
9
|
|
8
10
|
JSON::LD parses and serializes [JSON-LD][] into [RDF][] and implements expansion, compaction and framing API interfaces.
|
@@ -206,11 +208,20 @@ Install with `gem install json-ld`
|
|
206
208
|
## Documentation
|
207
209
|
Full documentation available on [RubyDoc](http://rubydoc.info/gems/json-ld/file/README.markdown)
|
208
210
|
|
211
|
+
## Differences from [JSON-LD API][]
|
212
|
+
The specified JSON-LD API is based on a WebIDL definition intended for use within the browser.
|
213
|
+
This version implements a more Ruby-like variation of this API without the use
|
214
|
+
of futures and callback arguments, preferring Ruby blocks. All API methods
|
215
|
+
execute synchronously, so that the return from a method can be used as well as a block.
|
216
|
+
|
217
|
+
Note, the API method signatures differed in versions before 1.0, in that they also had
|
218
|
+
a callback parameter.
|
219
|
+
|
209
220
|
### Principal Classes
|
210
221
|
* {JSON::LD}
|
211
222
|
* {JSON::LD::API}
|
212
223
|
* {JSON::LD::Compact}
|
213
|
-
* {JSON::LD::
|
224
|
+
* {JSON::LD::Context}
|
214
225
|
* {JSON::LD::Format}
|
215
226
|
* {JSON::LD::Frame}
|
216
227
|
* {JSON::LD::FromRDF}
|
@@ -219,7 +230,7 @@ Full documentation available on [RubyDoc](http://rubydoc.info/gems/json-ld/file/
|
|
219
230
|
* {JSON::LD::Writer}
|
220
231
|
|
221
232
|
## Dependencies
|
222
|
-
* [Ruby](http://ruby-lang.org/) (>= 1.
|
233
|
+
* [Ruby](http://ruby-lang.org/) (>= 1.9.2)
|
223
234
|
* [RDF.rb](http://rubygems.org/gems/rdf) (>= 1.0)
|
224
235
|
* [JSON](https://rubygems.org/gems/json) (>= 1.5)
|
225
236
|
|
@@ -267,3 +278,4 @@ see <http://unlicense.org/> or the accompanying {file:UNLICENSE} file.
|
|
267
278
|
[RDF.rb]: http://rubygems.org/gems/rdf
|
268
279
|
[Backports]: http://rubygems.org/gems/backports
|
269
280
|
[JSON-LD]: http://json-ld.org/spec/latest/
|
281
|
+
[JSON-LD API]: http://json-ld.org/spec/latest/json-ld-api/
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
1.0.0
|
data/lib/json/ld.rb
CHANGED
@@ -26,7 +26,7 @@ module JSON
|
|
26
26
|
require 'json/ld/format'
|
27
27
|
require 'json/ld/utils'
|
28
28
|
autoload :API, 'json/ld/api'
|
29
|
-
autoload :
|
29
|
+
autoload :Context, 'json/ld/context'
|
30
30
|
autoload :Normalize, 'json/ld/normalize'
|
31
31
|
autoload :Reader, 'json/ld/reader'
|
32
32
|
autoload :Resource, 'json/ld/resource'
|
@@ -40,11 +40,20 @@ module JSON
|
|
40
40
|
}.freeze
|
41
41
|
|
42
42
|
KEYWORDS = %w(
|
43
|
+
@base
|
43
44
|
@container
|
44
45
|
@context
|
46
|
+
@default
|
47
|
+
@embed
|
48
|
+
@embedChildren
|
49
|
+
@explicit
|
45
50
|
@id
|
51
|
+
@index
|
52
|
+
@graph
|
46
53
|
@language
|
47
54
|
@list
|
55
|
+
@omitDefault
|
56
|
+
@reverse
|
48
57
|
@set
|
49
58
|
@type
|
50
59
|
@value
|
@@ -80,98 +89,52 @@ module JSON
|
|
80
89
|
def self.debug=(value); @debug = value; end
|
81
90
|
|
82
91
|
class ProcessingError < Exception
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
class
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
end
|
103
|
-
|
104
|
-
class Conflict < ProcessingError
|
105
|
-
def initialize(*args)
|
106
|
-
super
|
107
|
-
@code = CONFLICTING_DATATYPES
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
class LanguageMap < ProcessingError
|
112
|
-
def initialize(*args)
|
113
|
-
super
|
114
|
-
@code = ILLEGAL_LANGUAGE_MAP_DETECTED
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
class ListOfLists < ProcessingError
|
119
|
-
def initialize(*args)
|
120
|
-
super
|
121
|
-
@code = LIST_OF_LISTS_DETECTED
|
122
|
-
end
|
123
|
-
end
|
92
|
+
class CompactionToListOfLists < ProcessingError; end
|
93
|
+
class Conflict < ProcessingError; end
|
94
|
+
class ConflictingIndexes < ProcessingError; end
|
95
|
+
class InvalidIdValue < ProcessingError; end
|
96
|
+
class InvalidIndexValue < ProcessingError; end
|
97
|
+
class InvalidLanguageMapValue < ProcessingError; end
|
98
|
+
class InvalidLanguageTaggedString < ProcessingError; end
|
99
|
+
class InvalidLanguageTaggedValue < ProcessingError; end
|
100
|
+
class InvalidReversePropertyMap < ProcessingError; end
|
101
|
+
class InvalidReversePropertyValue < ProcessingError; end
|
102
|
+
class InvalidReverseValue < ProcessingError; end
|
103
|
+
class InvalidSetOrListObject < ProcessingError; end
|
104
|
+
class InvalidTypedValue < ProcessingError; end
|
105
|
+
class InvalidTypeValue < ProcessingError; end
|
106
|
+
class InvalidValueObject < ProcessingError; end
|
107
|
+
class InvalidValueObjectValue < ProcessingError; end
|
108
|
+
class LanguageMap < ProcessingError; end
|
109
|
+
class ListOfLists < ProcessingError; end
|
110
|
+
class LoadingDocumentFailed < ProcessingError; end
|
111
|
+
class Lossy < ProcessingError; end
|
124
112
|
end
|
125
113
|
|
126
114
|
class InvalidContext < Exception
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
class
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
end
|
142
|
-
|
143
|
-
class
|
144
|
-
|
145
|
-
super
|
146
|
-
@code = LOAD_ERROR
|
147
|
-
end
|
148
|
-
end
|
115
|
+
class CollidingKeywords < InvalidContext; end
|
116
|
+
class CyclicIRIMapping < InvalidContext; end
|
117
|
+
class InvalidBaseIRI < InvalidContext; end
|
118
|
+
class InvalidBaseIRI < InvalidContext; end
|
119
|
+
class InvalidContainerMapping < InvalidContext; end
|
120
|
+
class InvalidDefaultLanguage < InvalidContext; end
|
121
|
+
class InvalidIRIMapping < InvalidContext; end
|
122
|
+
class InvalidKeywordAlias < InvalidContext; end
|
123
|
+
class InvalidLanguageMapping < InvalidContext; end
|
124
|
+
class InvalidLocalContext < InvalidContext; end
|
125
|
+
class InvalidRemoteContext < InvalidContext; end
|
126
|
+
class InvalidReverseProperty < InvalidContext; end
|
127
|
+
class InvalidTermDefinition < InvalidContext; end
|
128
|
+
class InvalidTypeMapping < InvalidContext; end
|
129
|
+
class InvalidVocabMapping < InvalidContext; end
|
130
|
+
class KeywordRedefinition < InvalidContext; end
|
131
|
+
class LoadingRemoteContextFailed < InvalidContext; end
|
132
|
+
class RecursiveContextInclusion < InvalidContext; end
|
149
133
|
end
|
150
134
|
|
151
135
|
class InvalidFrame < Exception
|
152
|
-
|
153
|
-
|
154
|
-
INVALID_SYNTAX = 1
|
155
|
-
|
156
|
-
# A subject IRI was specified in more than one place in the input frame.
|
157
|
-
# More than one embed of a given subject IRI is not allowed, and if requested, must result in this exception.
|
158
|
-
MULTIPLE_EMBEDS = 2
|
159
|
-
|
160
|
-
attr_reader :code
|
161
|
-
|
162
|
-
class Syntax < InvalidFrame
|
163
|
-
def initialize(*args)
|
164
|
-
super
|
165
|
-
@code = INVALID_SYNTAX
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
class MultipleEmbeds < InvalidFrame
|
170
|
-
def initialize(*args)
|
171
|
-
super
|
172
|
-
@code = MULTIPLE_EMBEDS
|
173
|
-
end
|
174
|
-
end
|
136
|
+
class MultipleEmbeds < InvalidFrame; end
|
137
|
+
class Syntax < InvalidFrame; end
|
175
138
|
end
|
176
139
|
end
|
177
140
|
end
|
data/lib/json/ld/api.rb
CHANGED
@@ -8,11 +8,11 @@ require 'json/ld/from_rdf'
|
|
8
8
|
|
9
9
|
module JSON::LD
|
10
10
|
##
|
11
|
-
# A JSON-LD processor
|
11
|
+
# A JSON-LD processor based on the JsonLdProcessor interface.
|
12
12
|
#
|
13
|
-
# This API provides a clean mechanism that enables developers to convert JSON-LD data into a a variety of output formats that
|
14
|
-
#
|
15
|
-
#
|
13
|
+
# This API provides a clean mechanism that enables developers to convert JSON-LD data into a a variety of output formats that are easier to work with in various programming languages. If a JSON-LD API is provided in a programming environment, the entirety of the following API must be implemented.
|
14
|
+
#
|
15
|
+
# Note that the API method signatures are somewhat different than what is specified, as the use of Futures and explicit callback parameters is not as relevant for Ruby-based interfaces.
|
16
16
|
#
|
17
17
|
# @see http://json-ld.org/spec/latest/json-ld-api/#the-application-programming-interface
|
18
18
|
# @author [Gregg Kellogg](http://greggkellogg.net/)
|
@@ -36,7 +36,7 @@ module JSON::LD
|
|
36
36
|
|
37
37
|
# Input evaluation context
|
38
38
|
# @!attribute [rw] context
|
39
|
-
# @return [JSON::LD::
|
39
|
+
# @return [JSON::LD::Context]
|
40
40
|
attr_accessor :context
|
41
41
|
|
42
42
|
# Current Blank Node Namer
|
@@ -48,15 +48,13 @@ module JSON::LD
|
|
48
48
|
# Initialize the API, reading in any document and setting global options
|
49
49
|
#
|
50
50
|
# @param [String, #read, Hash, Array] input
|
51
|
-
# @param [String, #read,, Hash, Array, JSON::LD::
|
51
|
+
# @param [String, #read,, Hash, Array, JSON::LD::Context] context
|
52
52
|
# An external context to use additionally to the context embedded in input when expanding the input.
|
53
53
|
# @param [Hash{Symbol => Object}] options
|
54
54
|
# @option options [Boolean] :base
|
55
55
|
# The Base IRI to use when expanding the document. This overrides the value of `input` if it is a _IRI_. If not specified and `input` is not an _IRI_, the base IRI defaults to the current document IRI if in a browser context, or the empty string if there is no document context.
|
56
56
|
# @option options [Boolean] :compactArrays (true)
|
57
57
|
# If set to `true`, the JSON-LD processor replaces arrays with just one element with that element during compaction. If set to `false`, all arrays will remain arrays even if they have just one element.
|
58
|
-
# @option options [Proc] :conformanceCallback
|
59
|
-
# The purpose of this option is to instruct the processor about whether or not it should continue processing. If the value is null, the processor should ignore any key-value pair associated with any recoverable conformance issue and continue processing. More details about this feature can be found in the ConformanceCallback section.
|
60
58
|
# @option options [Boolean, String, RDF::URI] :flatten
|
61
59
|
# 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.
|
62
60
|
# @option options [Boolean] :optimize (false)
|
@@ -73,7 +71,7 @@ module JSON::LD
|
|
73
71
|
def initialize(input, context, options = {}, &block)
|
74
72
|
@options = {:compactArrays => true}.merge(options)
|
75
73
|
options = {:rename_bnodes => true}.merge(options)
|
76
|
-
@namer = options[:rename_bnodes] ? BlankNodeNamer.new("
|
74
|
+
@namer = options[:rename_bnodes] ? BlankNodeNamer.new("b") : BlankNodeMapper.new
|
77
75
|
@value = case input
|
78
76
|
when Array, Hash then input.dup
|
79
77
|
when IO, StringIO then JSON.parse(input.read)
|
@@ -83,7 +81,7 @@ module JSON::LD
|
|
83
81
|
RDF::Util::File.open_file(input, OPEN_OPTS) {|f| content = JSON.parse(f.read)}
|
84
82
|
content
|
85
83
|
end
|
86
|
-
@context =
|
84
|
+
@context = Context.new(@options)
|
87
85
|
@context = @context.parse(context) if context
|
88
86
|
|
89
87
|
if block_given?
|
@@ -98,16 +96,12 @@ module JSON::LD
|
|
98
96
|
# Expands the given input according to the steps in the Expansion Algorithm. The input must be copied, expanded and returned
|
99
97
|
# if there are no errors. If the expansion fails, an appropriate exception must be thrown.
|
100
98
|
#
|
101
|
-
# The resulting `Array`
|
102
|
-
#
|
103
|
-
# Note that for Ruby, if the callback is not provided and a block is given, it will be yielded
|
99
|
+
# The resulting `Array` either returned or yielded
|
104
100
|
#
|
105
101
|
# @param [String, #read, Hash, Array] input
|
106
102
|
# The JSON-LD object to copy and perform the expansion upon.
|
107
|
-
# @param [String, #read, Hash, Array, JSON::LD::
|
103
|
+
# @param [String, #read, Hash, Array, JSON::LD::Context] context
|
108
104
|
# An external context to use additionally to the context embedded in input when expanding the input.
|
109
|
-
# @param [Proc] callback (&block)
|
110
|
-
# Alternative to using block, with same parameters.
|
111
105
|
# @param [Hash{Symbol => Object}] options
|
112
106
|
# See options in {JSON::LD::API#initialize}
|
113
107
|
# @raise [InvalidContext]
|
@@ -117,7 +111,7 @@ module JSON::LD
|
|
117
111
|
# @return [Array<Hash>]
|
118
112
|
# The expanded JSON-LD document
|
119
113
|
# @see http://json-ld.org/spec/latest/json-ld-api/#expansion-algorithm
|
120
|
-
def self.expand(input, context = nil,
|
114
|
+
def self.expand(input, context = nil, options = {})
|
121
115
|
result = nil
|
122
116
|
API.new(input, context, options) do |api|
|
123
117
|
result = api.expand(api.value, nil, api.context)
|
@@ -129,7 +123,6 @@ module JSON::LD
|
|
129
123
|
|
130
124
|
# Finally, if element is a JSON object, it is wrapped into an array.
|
131
125
|
result = [result].compact unless result.is_a?(Array)
|
132
|
-
callback.call(result) if callback
|
133
126
|
yield result if block_given?
|
134
127
|
result
|
135
128
|
end
|
@@ -140,16 +133,12 @@ module JSON::LD
|
|
140
133
|
#
|
141
134
|
# If no context is provided, the input document is compacted using the top-level context of the document
|
142
135
|
#
|
143
|
-
# The resulting `Hash` is returned
|
144
|
-
#
|
145
|
-
# Note that for Ruby, if the callback is not provided and a block is given, it will be yielded
|
136
|
+
# The resulting `Hash` is either returned or yielded, if a block is given.
|
146
137
|
#
|
147
138
|
# @param [String, #read, Hash, Array] input
|
148
139
|
# The JSON-LD object to copy and perform the compaction upon.
|
149
|
-
# @param [String, #read, Hash, Array, JSON::LD::
|
140
|
+
# @param [String, #read, Hash, Array, JSON::LD::Context] context
|
150
141
|
# The base context to use when compacting the input.
|
151
|
-
# @param [Proc] callback (&block)
|
152
|
-
# Alternative to using block, with same parameters.
|
153
142
|
# @param [Hash{Symbol => Object}] options
|
154
143
|
# See options in {JSON::LD::API#initialize}
|
155
144
|
# Other options passed to {JSON::LD::API.expand}
|
@@ -160,48 +149,38 @@ module JSON::LD
|
|
160
149
|
# The compacted JSON-LD document
|
161
150
|
# @raise [InvalidContext, ProcessingError]
|
162
151
|
# @see http://json-ld.org/spec/latest/json-ld-api/#compaction-algorithm
|
163
|
-
def self.compact(input, context,
|
152
|
+
def self.compact(input, context, options = {})
|
164
153
|
expanded = result = nil
|
165
154
|
|
166
155
|
# 1) Perform the Expansion Algorithm on the JSON-LD input.
|
167
156
|
# This removes any existing context to allow the given context to be cleanly applied.
|
168
|
-
expanded = API.expand(input, nil,
|
157
|
+
expanded = API.expand(input, nil, options.merge(:debug => nil))
|
169
158
|
|
170
159
|
API.new(expanded, context, options) do
|
171
160
|
debug(".compact") {"expanded input: #{expanded.to_json(JSON_STATE)}"}
|
172
161
|
result = compact(value, nil)
|
173
162
|
|
174
163
|
# xxx) Add the given context to the output
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
self.context.serialize.merge(kwgraph => result)
|
180
|
-
when String
|
181
|
-
kwid = self.context.compact_iri('@id', :quiet => true)
|
182
|
-
self.context.serialize.merge(kwid => result)
|
164
|
+
ctx = self.context.serialize
|
165
|
+
if result.is_a?(Array)
|
166
|
+
kwgraph = self.context.compact_iri('@graph', :vocab => true, :quiet => true)
|
167
|
+
result = result.empty? ? {} : {kwgraph => result}
|
183
168
|
end
|
169
|
+
result = ctx.merge(result) unless ctx.empty?
|
184
170
|
end
|
185
|
-
callback.call(result) if callback
|
186
171
|
yield result if block_given?
|
187
172
|
result
|
188
173
|
end
|
189
174
|
|
190
175
|
##
|
191
|
-
#
|
192
|
-
#
|
193
|
-
# The resulting `Array` is returned via the provided callback.
|
176
|
+
# This algorithm flattens an expanded JSON-LD document by collecting all properties of a node in a single JSON object and labeling all blank nodes with blank node identifiers. This resulting uniform shape of the document, may drastically simplify the code required to process JSON-LD data in certain applications.
|
194
177
|
#
|
195
|
-
#
|
178
|
+
# The resulting `Array` is either returned, or yielded if a block is given.
|
196
179
|
#
|
197
180
|
# @param [String, #read, Hash, Array] input
|
198
181
|
# The JSON-LD object or array of JSON-LD objects to flatten or an IRI referencing the JSON-LD document to flatten.
|
199
|
-
# @param [String, RDF::URI] graph
|
200
|
-
# The graph in the document that should be flattened. To return the default graph @default has to be passed, for the merged graph @merged and for any other graph the IRI identifying the graph has to be passed. The default value is @merged.
|
201
182
|
# @param [String, #read, Hash, Array, JSON::LD::EvaluationContext] context
|
202
183
|
# An optional external context to use additionally to the context embedded in input when expanding the input.
|
203
|
-
# @param [Proc] callback (&block)
|
204
|
-
# Alternative to using block, with same parameters.
|
205
184
|
# @param [Hash{Symbol => Object}] options
|
206
185
|
# See options in {JSON::LD::API#initialize}
|
207
186
|
# Other options passed to {JSON::LD::API.expand}
|
@@ -212,38 +191,45 @@ module JSON::LD
|
|
212
191
|
# The framed JSON-LD document
|
213
192
|
# @raise [InvalidFrame]
|
214
193
|
# @see http://json-ld.org/spec/latest/json-ld-api/#framing-algorithm
|
215
|
-
def self.flatten(input,
|
216
|
-
|
217
|
-
graph ||= '@merged'
|
194
|
+
def self.flatten(input, context, options = {})
|
195
|
+
flattened = []
|
218
196
|
|
219
197
|
# Expand input to simplify processing
|
220
|
-
expanded_input = API.expand(input)
|
198
|
+
expanded_input = API.expand(input, nil, options)
|
221
199
|
|
222
200
|
# Initialize input using frame as context
|
223
201
|
API.new(expanded_input, nil, options) do
|
224
202
|
debug(".flatten") {"expanded input: #{value.to_json(JSON_STATE)}"}
|
225
203
|
|
226
|
-
#
|
204
|
+
# Initialize node map to a JSON object consisting of a single member whose key is @default and whose value is an empty JSON object.
|
227
205
|
node_map = Hash.ordered
|
228
|
-
|
229
|
-
|
230
|
-
result = []
|
206
|
+
node_map['@default'] = Hash.ordered
|
207
|
+
self.generate_node_map(value, node_map)
|
231
208
|
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
209
|
+
default_graph = node_map['@default']
|
210
|
+
node_map.keys.kw_sort.reject {|k| k == '@default'}.each do |graph_name|
|
211
|
+
graph = node_map[graph_name]
|
212
|
+
entry = default_graph[graph_name] ||= {'@id' => graph_name}
|
213
|
+
nodes = entry['@graph'] ||= []
|
214
|
+
graph.keys.kw_sort.each do |id|
|
215
|
+
nodes << graph[id]
|
216
|
+
end
|
217
|
+
end
|
218
|
+
default_graph.keys.kw_sort.each do |id|
|
219
|
+
flattened << default_graph[id]
|
220
|
+
end
|
221
|
+
|
222
|
+
if context && !flattened.empty?
|
223
|
+
# Otherwise, return the result of compacting flattened according the Compaction algorithm passing context ensuring that the compaction result uses the @graph keyword (or its alias) at the top-level, even if the context is empty or if there is only one element to put in the @graph array. This ensures that the returned document has a deterministic structure.
|
224
|
+
compacted = compact(flattened, nil)
|
225
|
+
compacted = [compacted] unless compacted.is_a?(Array)
|
226
|
+
kwgraph = self.context.compact_iri('@graph', :quiet => true)
|
227
|
+
flattened = self.context.serialize.merge(kwgraph => compacted)
|
239
228
|
end
|
240
|
-
|
241
|
-
result
|
242
229
|
end
|
243
230
|
|
244
|
-
|
245
|
-
|
246
|
-
result
|
231
|
+
yield flattened if block_given?
|
232
|
+
flattened
|
247
233
|
end
|
248
234
|
|
249
235
|
##
|
@@ -251,16 +237,12 @@ module JSON::LD
|
|
251
237
|
# framed output and is returned if there are no errors. If there are no matches for the frame, null must be returned.
|
252
238
|
# Exceptions must be thrown if there are errors.
|
253
239
|
#
|
254
|
-
# The resulting `Array` is returned
|
255
|
-
#
|
256
|
-
# Note that for Ruby, if the callback is not provided and a block is given, it will be yielded
|
240
|
+
# The resulting `Array` is either returned, or yielded if a block is given.
|
257
241
|
#
|
258
242
|
# @param [String, #read, Hash, Array] input
|
259
243
|
# The JSON-LD object to copy and perform the framing on.
|
260
244
|
# @param [String, #read, Hash, Array] frame
|
261
245
|
# The frame to use when re-arranging the data.
|
262
|
-
# @param [Proc] callback (&block)
|
263
|
-
# Alternative to using block, with same parameters.
|
264
246
|
# @param [Hash{Symbol => Object}] options
|
265
247
|
# See options in {JSON::LD::API#initialize}
|
266
248
|
# Other options passed to {JSON::LD::API.expand}
|
@@ -280,7 +262,7 @@ module JSON::LD
|
|
280
262
|
# The framed JSON-LD document
|
281
263
|
# @raise [InvalidFrame]
|
282
264
|
# @see http://json-ld.org/spec/latest/json-ld-api/#framing-algorithm
|
283
|
-
def self.frame(input, frame,
|
265
|
+
def self.frame(input, frame, options = {})
|
284
266
|
result = nil
|
285
267
|
match_limit = 0
|
286
268
|
framing_state = {
|
@@ -312,19 +294,22 @@ module JSON::LD
|
|
312
294
|
# Initialize input using frame as context
|
313
295
|
API.new(expanded_input, nil, options) do
|
314
296
|
#debug(".frame") {"context from frame: #{context.inspect}"}
|
315
|
-
|
316
|
-
|
297
|
+
debug(".frame") {"raw frame: #{frame.to_json(JSON_STATE)}"}
|
298
|
+
debug(".frame") {"expanded frame: #{expanded_frame.to_json(JSON_STATE)}"}
|
299
|
+
debug(".frame") {"expanded input: #{value.to_json(JSON_STATE)}"}
|
317
300
|
|
318
301
|
# Get framing nodes from expanded input, replacing Blank Node identifiers as necessary
|
319
302
|
all_nodes = Hash.ordered
|
303
|
+
old_dbg, @options[:debug] = @options[:debug], nil
|
320
304
|
depth do
|
321
305
|
generate_node_map(value, all_nodes, '@merged')
|
322
306
|
end
|
307
|
+
@options[:debug] = old_dbg
|
323
308
|
@node_map = all_nodes['@merged']
|
324
309
|
debug(".frame") {"node_map: #{@node_map.to_json(JSON_STATE)}"}
|
325
310
|
|
326
311
|
result = []
|
327
|
-
frame(framing_state, @node_map, expanded_frame
|
312
|
+
frame(framing_state, @node_map, (expanded_frame.first || {}), result, nil)
|
328
313
|
debug(".frame") {"after frame: #{result.to_json(JSON_STATE)}"}
|
329
314
|
|
330
315
|
# Initalize context from frame
|
@@ -340,7 +325,6 @@ module JSON::LD
|
|
340
325
|
result = cleanup_preserve(result)
|
341
326
|
end
|
342
327
|
|
343
|
-
callback.call(result) if callback
|
344
328
|
yield result if block_given?
|
345
329
|
result
|
346
330
|
end
|
@@ -348,14 +332,10 @@ module JSON::LD
|
|
348
332
|
##
|
349
333
|
# Processes the input according to the RDF Conversion Algorithm, calling the provided callback for each triple generated.
|
350
334
|
#
|
351
|
-
# Note that for Ruby, if the callback is not provided and a block is given, it will be yielded
|
352
|
-
#
|
353
335
|
# @param [String, #read, Hash, Array] input
|
354
336
|
# The JSON-LD object to process when outputting statements.
|
355
|
-
# @param [String, #read, Hash, Array, JSON::LD::
|
337
|
+
# @param [String, #read, Hash, Array, JSON::LD::Context] context
|
356
338
|
# An external context to use additionally to the context embedded in input when expanding the input.
|
357
|
-
# @param [Proc] callback (&block)
|
358
|
-
# Alternative to using block, with same parameteres.
|
359
339
|
# @param [{Symbol,String => Object}] options
|
360
340
|
# See options in {JSON::LD::API#initialize}
|
361
341
|
# Options passed to {JSON::LD::API.expand}
|
@@ -363,21 +343,35 @@ module JSON::LD
|
|
363
343
|
# @return [Array<RDF::Statement>] if no block given
|
364
344
|
# @yield statement
|
365
345
|
# @yieldparam [RDF::Statement] statement
|
366
|
-
def self.toRDF(input, context = nil,
|
346
|
+
def self.toRDF(input, context = nil, options = {}, &block)
|
367
347
|
results = []
|
368
|
-
|
348
|
+
results.extend(RDF::Enumerable)
|
349
|
+
|
350
|
+
# Expand input to simplify processing
|
351
|
+
expanded_input = API.expand(input, context, options)
|
352
|
+
|
353
|
+
API.new(expanded_input, context, options) do
|
369
354
|
# 1) Perform the Expansion Algorithm on the JSON-LD input.
|
370
355
|
# This removes any existing context to allow the given context to be cleanly applied.
|
371
|
-
|
356
|
+
debug(".toRDF") {"expanded input: #{expanded_input.to_json(JSON_STATE)}"}
|
357
|
+
|
358
|
+
# Generate _nodeMap_
|
359
|
+
node_map = Hash.ordered
|
360
|
+
node_map['@default'] = Hash.ordered
|
361
|
+
generate_node_map(expanded_input, node_map)
|
362
|
+
debug(".toRDF") {"node map: #{node_map.to_json(JSON_STATE)}"}
|
372
363
|
|
373
|
-
api.send(:debug, ".expand") {"expanded input: #{result.to_json(JSON_STATE)}"}
|
374
364
|
# Start generating statements
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
365
|
+
node_map.each do |graph_name, graph|
|
366
|
+
context = as_resource(graph_name) unless graph_name == '@default'
|
367
|
+
debug(".toRDF") {"context: #{context ? context.to_ntriples : 'null'}"}
|
368
|
+
graph_to_rdf(graph).each do |statement|
|
369
|
+
statement.context = context if context
|
370
|
+
if block_given?
|
371
|
+
yield statement
|
372
|
+
else
|
373
|
+
results << statement
|
374
|
+
end
|
381
375
|
end
|
382
376
|
end
|
383
377
|
end
|
@@ -387,13 +381,9 @@ module JSON::LD
|
|
387
381
|
##
|
388
382
|
# Take an ordered list of RDF::Statements and turn them into a JSON-LD document.
|
389
383
|
#
|
390
|
-
# The resulting `Array` is returned
|
391
|
-
#
|
392
|
-
# Note that for Ruby, if the callback is not provided and a block is given, it will be yielded
|
384
|
+
# The resulting `Array` is either returned or yielded, if a block is given.
|
393
385
|
#
|
394
386
|
# @param [Array<RDF::Statement>] input
|
395
|
-
# @param [Proc] callback (&block)
|
396
|
-
# Alternative to using block, with same parameteres.
|
397
387
|
# @param [Hash{Symbol => Object}] options
|
398
388
|
# See options in {JSON::LD::API#initialize}
|
399
389
|
# @yield jsonld
|
@@ -401,7 +391,7 @@ module JSON::LD
|
|
401
391
|
# The JSON-LD document in expanded form
|
402
392
|
# @return [Array<Hash>]
|
403
393
|
# The JSON-LD document in expanded form
|
404
|
-
def self.fromRDF(input,
|
394
|
+
def self.fromRDF(input, options = {}, &block)
|
405
395
|
options = {:useNativeTypes => true}.merge(options)
|
406
396
|
result = nil
|
407
397
|
|
@@ -409,8 +399,7 @@ module JSON::LD
|
|
409
399
|
result = api.from_statements(input)
|
410
400
|
end
|
411
401
|
|
412
|
-
|
413
|
-
callback.call(result) if callback
|
402
|
+
yield result if block_given?
|
414
403
|
result
|
415
404
|
end
|
416
405
|
end
|