json-ld 0.9.1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
data/lib/json/ld/extensions.rb
CHANGED
@@ -32,6 +32,13 @@ module RDF
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
+
class Node
|
36
|
+
# Odd case of appending to a BNode identifier
|
37
|
+
def +(value)
|
38
|
+
Node.new(id + value.to_s)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
35
42
|
class Literal
|
36
43
|
class Double
|
37
44
|
##
|
@@ -63,8 +70,9 @@ class Array
|
|
63
70
|
# @yieldparam [Object] b
|
64
71
|
# @yieldreturn [Integer]
|
65
72
|
# @return [Array]
|
66
|
-
KW_ORDER = %(@id @value @type @language @vocab @container @graph @list @set)
|
73
|
+
KW_ORDER = %w(@base @id @value @type @language @vocab @container @graph @list @set @index).freeze
|
67
74
|
|
75
|
+
# Order, considering keywords to come before other strings
|
68
76
|
def kw_sort
|
69
77
|
self.sort do |a, b|
|
70
78
|
a = "@#{KW_ORDER.index(a)}" if KW_ORDER.include?(a)
|
@@ -72,6 +80,14 @@ class Array
|
|
72
80
|
a <=> b
|
73
81
|
end
|
74
82
|
end
|
83
|
+
|
84
|
+
# Order terms, length first, then lexographically
|
85
|
+
def term_sort
|
86
|
+
self.sort do |a, b|
|
87
|
+
len_diff = a.length <=> b.length
|
88
|
+
len_diff == 0 ? a <=> b : len_diff
|
89
|
+
end
|
90
|
+
end
|
75
91
|
end
|
76
92
|
|
77
93
|
if RUBY_VERSION < "1.9"
|
data/lib/json/ld/flatten.rb
CHANGED
@@ -3,104 +3,171 @@ module JSON::LD
|
|
3
3
|
include Utils
|
4
4
|
|
5
5
|
##
|
6
|
-
#
|
6
|
+
# This algorithm creates a JSON object node map holding an indexed representation of the graphs and nodes represented in the passed expanded document. All nodes that are not uniquely identified by an IRI get assigned a (new) blank node identifier. The resulting node map will have a member for every graph in the document whose value is another object with a member for every node represented in the document. The default graph is stored under the @default member, all other graphs are stored under their graph name.
|
7
7
|
#
|
8
8
|
# @param [Array, Hash] element
|
9
9
|
# Expanded element
|
10
10
|
# @param [Hash{String => Hash}] node_map
|
11
11
|
# map of nodes
|
12
|
-
# @param [String]
|
12
|
+
# @param [String] active_graph
|
13
13
|
# Graph name for results
|
14
14
|
# @param [Array] list
|
15
15
|
# List for saving list elements
|
16
16
|
# @param [String] id (nil)
|
17
17
|
# Identifier already associated with element
|
18
|
-
def generate_node_map(element,
|
18
|
+
def generate_node_map(element,
|
19
|
+
node_map,
|
20
|
+
active_graph = '@default',
|
21
|
+
active_subject = nil,
|
22
|
+
active_property = nil,
|
23
|
+
list = nil)
|
19
24
|
depth do
|
20
|
-
debug("
|
25
|
+
debug("node_map") {"active_graph: #{active_graph}, element: #{element.inspect}"}
|
21
26
|
if element.is_a?(Array)
|
22
|
-
element
|
23
|
-
|
24
|
-
|
27
|
+
# If element is an array, process each entry in element recursively, using this algorithm and return
|
28
|
+
element.map {|o|
|
29
|
+
generate_node_map(o,
|
30
|
+
node_map,
|
31
|
+
active_graph,
|
32
|
+
active_subject,
|
33
|
+
active_property,
|
34
|
+
list)
|
35
|
+
}
|
25
36
|
else
|
26
|
-
#
|
27
|
-
# FIXME:
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
when /^@(?!type)/
|
52
|
-
# If property is not @type and is a keyword, merge property and value into node and then continue.
|
53
|
-
debug("nodeMap") {"merge keyword#{prop}: #{value.inspect}"}
|
54
|
-
node[prop] = value
|
37
|
+
# Otherwise element is a JSON object. Reference the JSON object which is the value of the active graph member of node map using the variable graph. If the active subject is null, set node to null otherwise reference the active subject member of graph using the variable node.
|
38
|
+
# Spec FIXME: initializing it to an empty JSON object, if necessary
|
39
|
+
raise "Expected element to be a hash, was #{element.class}" unless element.is_a?(Hash)
|
40
|
+
graph = node_map[active_graph] ||= Hash.ordered
|
41
|
+
node = graph[active_subject] if active_subject
|
42
|
+
|
43
|
+
# If element has an @type member, perform for each item the following steps:
|
44
|
+
if element.has_key?('@type')
|
45
|
+
types = [element['@type']].flatten.map do |item|
|
46
|
+
# If item is a blank node identifier, replace it with a newly generated blank node identifier passing item for identifier.
|
47
|
+
item = namer.get_name(item) if blank_node?(item)
|
48
|
+
|
49
|
+
# If graph has no member item, create it and initialize its value to a JSON object consisting of a single member @id with the value item.
|
50
|
+
graph[item] ||= {'@id' => item}
|
51
|
+
item
|
52
|
+
end
|
53
|
+
|
54
|
+
element['@type'] = element['@type'].is_a?(Array) ? types : types.first
|
55
|
+
end
|
56
|
+
|
57
|
+
# If element has an @value member, perform the following steps:
|
58
|
+
if value?(element)
|
59
|
+
unless list
|
60
|
+
# If no list has been passed, merge element into the active property member of the active subject in graph.
|
61
|
+
merge_value(node, active_property, element)
|
55
62
|
else
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
63
|
+
# Otherwise, append element to the @list member of list.
|
64
|
+
merge_value(list, '@list', element)
|
65
|
+
end
|
66
|
+
elsif list?(element)
|
67
|
+
# Otherwise, if element has an @list member, perform the following steps:
|
68
|
+
# Initialize a new JSON object result having a single member @list whose value is initialized to an empty array.
|
69
|
+
result = {'@list' => []}
|
70
|
+
|
71
|
+
# Recursively call this algorithm passing the value of element's @list member as new element and result as list.
|
72
|
+
generate_node_map(element['@list'],
|
73
|
+
node_map,
|
74
|
+
active_graph,
|
75
|
+
active_subject,
|
76
|
+
active_property,
|
77
|
+
result)
|
78
|
+
|
79
|
+
# Append result to the the value of the active property member of node.
|
80
|
+
merge_value(node, active_property, result)
|
81
|
+
else
|
82
|
+
# Otherwise element is a node object, perform the following steps:
|
83
|
+
|
84
|
+
# If element has an @id member, set id to its value and remove the member from element. If id is a blank node identifier, replace it with a newly generated blank node identifier passing id for identifier.
|
85
|
+
# Otherwise, set id to the result of the Generate Blank Node Identifier algorithm passing null for identifier.
|
86
|
+
id = element.delete('@id')
|
87
|
+
id = namer.get_name(id) if blank_node?(id)
|
88
|
+
debug("node_map") {"id: #{id.inspect}"}
|
89
|
+
|
90
|
+
# If graph does not contain a member id, create one and initialize it to a JSON object consisting of a single member @id whose value is set to id.
|
91
|
+
graph[id] ||= Hash.ordered
|
92
|
+
graph[id]['@id'] ||= id
|
93
|
+
|
94
|
+
# If active property is not null, perform the following steps:
|
95
|
+
if active_property
|
96
|
+
# Create a new JSON object reference consisting of a single member @id whose value is id.
|
97
|
+
reference = Hash.ordered
|
98
|
+
reference['@id'] = id
|
99
|
+
|
100
|
+
# If list is null:
|
101
|
+
unless list
|
102
|
+
merge_value(node, active_property, reference)
|
103
|
+
else
|
104
|
+
merge_value(list, '@list', reference)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Reference the value of the id member of graph using the variable node.
|
109
|
+
node = graph[id]
|
110
|
+
|
111
|
+
# If element has an @type key, append each item of its associated array to the array associated with the @type key of node unless it is already in that array. Finally remove the @type member from element.
|
112
|
+
if element.has_key?('@type')
|
113
|
+
[element.delete('@type')].flatten.each do |t|
|
114
|
+
merge_value(node, '@type', t)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# If element has an @index member, set the @index member of node to its value. If node has already an @index member with a different value, a conflicting indexes error has been detected and processing is aborted. Otherwise, continue by removing the @index member from element.
|
119
|
+
if element.has_key?('@index')
|
120
|
+
raise ProcessingError::ConflictingIndexesError,
|
121
|
+
"Element already has index #{node['@index']} dfferent from #{element['@index']}" if
|
122
|
+
node['@index'] && node['@index'] != element['@index']
|
123
|
+
node['@index'] = element.delete('@index')
|
124
|
+
end
|
125
|
+
|
126
|
+
# If element has an @reverse member:
|
127
|
+
if element.has_key?('@reverse')
|
128
|
+
element.delete('@reverse').each do |property, values|
|
129
|
+
values.each do |value|
|
130
|
+
debug("node_map") {"@reverse(#{id}): #{value.inspect}"}
|
131
|
+
# If value has a property member, append referenced node to its value; otherwise create a property member whose value is an array containing referenced node.
|
132
|
+
merge_value(value, property, {'@id' => id})
|
133
|
+
|
134
|
+
# Recursively invoke this algorithm passing value for element, node map, and active graph.
|
135
|
+
generate_node_map(value,
|
136
|
+
node_map,
|
137
|
+
active_graph)
|
97
138
|
end
|
98
139
|
end
|
99
140
|
end
|
141
|
+
|
142
|
+
# If element has an @graph member, recursively invoke this algorithm passing the value of the @graph member for element, node map, and id for active graph before removing the @graph member from element.
|
143
|
+
if element.has_key?('@graph')
|
144
|
+
generate_node_map(element.delete('@graph'),
|
145
|
+
node_map,
|
146
|
+
id)
|
147
|
+
end
|
148
|
+
|
149
|
+
# Finally, for each key-value pair property-value in element ordered by property perform the following steps:
|
150
|
+
element.keys.sort.each do |property|
|
151
|
+
value = element[property]
|
152
|
+
|
153
|
+
# If property is a blank node identifier, replace it with a newly generated blank node identifier passing property for identifier.
|
154
|
+
property = namer.get_name(property) if blank_node?(property)
|
155
|
+
|
156
|
+
# If node does not have a property member, create one and initialize its value to an empty array.
|
157
|
+
node[property] ||= []
|
158
|
+
|
159
|
+
# Recursively invoke this algorithm passing value as new element, id as new active subject, and property as new active property.
|
160
|
+
generate_node_map(value,
|
161
|
+
node_map,
|
162
|
+
active_graph,
|
163
|
+
id,
|
164
|
+
property,
|
165
|
+
list)
|
166
|
+
end
|
100
167
|
end
|
101
168
|
end
|
102
169
|
|
103
|
-
debug("
|
170
|
+
debug("node_map") {node_map.to_json(JSON_STATE)}
|
104
171
|
end
|
105
172
|
end
|
106
173
|
end
|
data/lib/json/ld/frame.rb
CHANGED
@@ -255,7 +255,7 @@ module JSON::LD
|
|
255
255
|
|
256
256
|
def validate_frame(state, frame)
|
257
257
|
raise InvalidFrame::Syntax,
|
258
|
-
"Invalid JSON-LD syntax; a JSON-LD frame must be an object" unless frame.is_a?(Hash)
|
258
|
+
"Invalid JSON-LD syntax; a JSON-LD frame must be an object: #{frame.inspect}" unless frame.is_a?(Hash)
|
259
259
|
end
|
260
260
|
|
261
261
|
# Return value of @name in frame, or default from state if it doesn't exist
|
data/lib/json/ld/from_rdf.rb
CHANGED
@@ -11,11 +11,11 @@ module JSON::LD
|
|
11
11
|
# @param [Array<RDF::Statement>, RDF::Enumerable] input
|
12
12
|
# @return [Array<Hash>] the JSON-LD document in normalized form
|
13
13
|
def from_statements(input)
|
14
|
-
|
15
|
-
|
14
|
+
default_graph = {}
|
15
|
+
graph_map = {'@default' => default_graph}
|
16
16
|
|
17
17
|
value = nil
|
18
|
-
ec =
|
18
|
+
ec = Context.new
|
19
19
|
|
20
20
|
# Create a map for node to object representation
|
21
21
|
|
@@ -23,125 +23,95 @@ module JSON::LD
|
|
23
23
|
input.each do |statement|
|
24
24
|
debug("statement") { statement.to_nquads.chomp}
|
25
25
|
|
26
|
-
|
27
|
-
name = statement.context ? ec.expand_iri(statement.context).to_s : ''
|
26
|
+
name = statement.context ? ec.expand_iri(statement.context).to_s : '@default'
|
28
27
|
|
29
28
|
# Create a graph entry as needed
|
30
|
-
|
29
|
+
node_map = graph_map[name] ||= {}
|
30
|
+
default_graph[name] ||= {'@id' => name} unless name == '@default'
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
next
|
43
|
-
when RDF.rest
|
44
|
-
# If property is rdf:rest,
|
45
|
-
# and object is a blank node,
|
46
|
-
# create a new entry in _restMap_ for _name_ and _subject_ and a value being the
|
47
|
-
# result of IRI expansion on the object and continue to the next statement.
|
48
|
-
next unless statement.object.is_a?(RDF::Node)
|
49
|
-
|
50
|
-
listMap = graph[:listMap]
|
51
|
-
entry = listMap[subject] ||= {}
|
52
|
-
|
53
|
-
object_rep = ec.expand_iri(statement.object).to_s
|
54
|
-
entry[:rest] = object_rep
|
55
|
-
debug("rdf:rest") { "save entry for #{subject.inspect} #{entry.inspect}"}
|
32
|
+
subject = ec.expand_iri(statement.subject).to_s
|
33
|
+
node = node_map[subject] ||= {'@id' => subject}
|
34
|
+
|
35
|
+
# If object is an IRI or blank node identifier, does not equal rdf:nil, and node map does not have an object member, create one and initialize its value to a new JSON object consisting of a single member @id whose value is set to object.
|
36
|
+
node_map[statement.object.to_s] ||= {'@id' => statement.object.to_s} unless
|
37
|
+
statement.object.literal? || statement.object == RDF.nil
|
38
|
+
|
39
|
+
# If predicate equals rdf:type, and object is an IRI or blank node identifier, append object to the value of the @type member of node. If no such member exists, create one and initialize it to an array whose only item is object. Finally, continue to the next RDF triple.
|
40
|
+
if statement.predicate == RDF.type && statement.object.resource?
|
41
|
+
merge_value(node, '@type', statement.object.to_s)
|
56
42
|
next
|
57
43
|
end
|
58
44
|
|
59
|
-
#
|
60
|
-
|
61
|
-
|
62
|
-
# Get value from graph nodes for subject, initializing it to a new node declaration for subject if it does not exist
|
63
|
-
debug("@id") { "new subject: #{subject}"} unless graph[:nodes].has_key?(subject)
|
64
|
-
value = graph[:nodes][subject] ||= {'@id' => subject}
|
65
|
-
|
66
|
-
# If property is http://www.w3.org/1999/02/22-rdf-syntax-ns#type
|
67
|
-
# and the useRdfType option is not true
|
68
|
-
if statement.predicate == RDF.type && !@options[:useRdfType]
|
69
|
-
object = ec.expand_iri(statement.object).to_s
|
70
|
-
debug("@type") { object.inspect}
|
71
|
-
# append the string representation of object to the array value for the key @type, creating
|
72
|
-
# an entry if necessary
|
73
|
-
(value['@type'] ||= []) << object
|
74
|
-
# FIXME: 3.7) If object is a typed literal and the useNativeTypes option is set to true:
|
75
|
-
elsif statement.object == RDF.nil
|
76
|
-
# Otherwise, if object is http://www.w3.org/1999/02/22-rdf-syntax-ns#nil, let
|
77
|
-
# key be the string representation of predicate. Set the value
|
78
|
-
# for key to an empty @list representation {"@list": []}
|
79
|
-
key = ec.expand_iri(statement.predicate).to_s
|
80
|
-
(value[key] ||= []) << {"@list" => []}
|
45
|
+
# If object equals rdf:nil and predicate does not equal rdf:rest, set value to a new JSON object consisting of a single member @list whose value is set to an empty array.
|
46
|
+
value = if statement.object == RDF.nil && statement.predicate != RDF.rest
|
47
|
+
{'@list' => []}
|
81
48
|
else
|
82
|
-
|
83
|
-
|
84
|
-
# described in Value Expansion.
|
85
|
-
key = ec.expand_iri(statement.predicate).to_s
|
86
|
-
object = ec.expand_value(key, statement.object, @options)
|
87
|
-
if blank_node?(object)
|
88
|
-
# if object is an Unnamed Node, set as the head element in the listMap
|
89
|
-
# entry for object
|
90
|
-
listMap = graph[:listMap]
|
91
|
-
entry = listMap[object['@id']] ||= {}
|
92
|
-
entry[:head] = object
|
93
|
-
debug("bnode") { "save entry #{entry.inspect}"}
|
94
|
-
end
|
49
|
+
ec.expand_value(nil, statement.object, @options)
|
50
|
+
end
|
95
51
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
(
|
52
|
+
merge_value(node, statement.predicate.to_s, value)
|
53
|
+
|
54
|
+
# If object is a blank node identifier and predicate equals neither rdf:first nor rdf:rest, it might represent the head of a RDF list:
|
55
|
+
if statement.object.node? && ![RDF.first, RDF.rest].include?(statement.predicate)
|
56
|
+
merge_value(node_map[statement.object.to_s], :usages, value)
|
101
57
|
end
|
102
58
|
end
|
103
59
|
|
104
|
-
#
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
60
|
+
# For each name and graph object in graph map:
|
61
|
+
graph_map.each do |name, graph_object|
|
62
|
+
subjects = graph_object.keys
|
63
|
+
subjects.each do |subj|
|
64
|
+
next unless graph_object.has_key?(subj)
|
65
|
+
node = graph_object[subj]
|
66
|
+
next unless node[:usages].is_a?(Array) && node[:usages].length == 1
|
67
|
+
debug("list head") {node.to_json(JSON_STATE)}
|
68
|
+
value = node[:usages].first
|
69
|
+
list, list_nodes, subject = [], [], subj
|
70
|
+
|
71
|
+
while subject != RDF.nil.to_s && list
|
72
|
+
if node.nil? ||
|
73
|
+
!blank_node?(node) ||
|
74
|
+
node.keys.any? {|k| !["@id", :usages, RDF.first.to_s, RDF.rest.to_s].include?(k)} ||
|
75
|
+
!(f = node[RDF.first.to_s]).is_a?(Array) || f.length != 1 ||
|
76
|
+
!(r = node[RDF.rest.to_s]).is_a?(Array) || r.length != 1 || !node_reference?(r.first) ||
|
77
|
+
list_nodes.include?(subject)
|
78
|
+
|
79
|
+
debug("list") {"not valid list element: #{node.to_json(JSON_STATE)}"}
|
80
|
+
list = nil
|
81
|
+
else
|
82
|
+
list << f.first
|
83
|
+
list_nodes << node['@id']
|
84
|
+
subject = r.first['@id']
|
85
|
+
node = graph_object[subject]
|
86
|
+
debug("list") {"rest: #{node.to_json(JSON_STATE)}"}
|
87
|
+
list = nil if list_nodes.include?(subject)
|
119
88
|
end
|
120
89
|
end
|
90
|
+
|
91
|
+
next if list.nil?
|
92
|
+
value.delete('@id')
|
93
|
+
value['@list'] = list
|
94
|
+
list_nodes.each {|s| graph_object.delete(s)}
|
121
95
|
end
|
122
96
|
end
|
123
97
|
|
124
|
-
|
125
|
-
debug("
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
graphs[subject][:nodes][s]
|
98
|
+
result = []
|
99
|
+
debug("graph_map") {graph_map.to_json(JSON_STATE)}
|
100
|
+
default_graph.keys.sort.each do |subject|
|
101
|
+
node = default_graph[subject]
|
102
|
+
if graph_map.has_key?(subject)
|
103
|
+
node['@graph'] = []
|
104
|
+
graph_map[subject].keys.sort.each do |s|
|
105
|
+
n = graph_map[subject][s]
|
106
|
+
n.delete(:usages)
|
107
|
+
node['@graph'] << n
|
135
108
|
end
|
136
109
|
end
|
137
|
-
|
138
|
-
|
139
|
-
entry
|
110
|
+
node.delete(:usages)
|
111
|
+
result << node
|
140
112
|
end
|
141
|
-
|
142
|
-
|
143
|
-
debug("fromRDF") {array.to_json(JSON_STATE)}
|
144
|
-
array
|
113
|
+
debug("fromRDF") {result.to_json(JSON_STATE)}
|
114
|
+
result
|
145
115
|
end
|
146
116
|
end
|
147
117
|
end
|