Skip to content

Commit 4f0b002

Browse files
committed
Consider @preserve when compacting term values, as required for json-ld/json-ld.org#496.
1 parent 0276ccf commit 4f0b002

File tree

9 files changed

+107
-2
lines changed

9 files changed

+107
-2
lines changed

example-files/issue-496.rb

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
require 'pp'
2+
require 'linkeddata'
3+
4+
input = JSON.parse %({
5+
"@context": {
6+
"schema": "http://schema.org/",
7+
"name": "schema:name",
8+
"url": {"@id": "schema:url", "@type": "schema:URL"}
9+
},
10+
"name": "Jane Doe"
11+
})
12+
13+
frame = JSON.parse %({
14+
"@context": {
15+
"schema": "http://schema.org/",
16+
"name": "schema:name",
17+
"url": { "@id": "schema:url", "@type": "schema:URL"}
18+
},
19+
"name": {},
20+
"url": {"@default": {"@value": "http://example.com", "@type": "schema:URL"}}
21+
})
22+
23+
pp JSON::LD::API.frame(input, frame, logger: Logger.new(STDERR))

example-files/issue-499-frame.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{"@context": ["http://schema.org", {
2+
"maintainer": {"@type": "@id"}
3+
}],
4+
"@embed": "@always",
5+
"author": {
6+
"familyName": {},
7+
"affiliation":
8+
{"@default": "@null"}
9+
},
10+
"maintainer": {
11+
"familyName": { "@default": "none" }
12+
}
13+
}

example-files/issue-499.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"@context": "http://schema.org",
3+
"@type": "SoftwareSourceCode",
4+
"author":
5+
{
6+
"@type": "Person",
7+
"givenName": "Carl",
8+
"familyName": "Boettiger",
9+
"email": "cboettig@gmail.com",
10+
"@id": "http://orcid.org/0000-0002-1642-628X"
11+
},
12+
"maintainer": "http://orcid.org/0000-0002-1642-628X"
13+
}

example-files/mitar-in.jsonld

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"@context": {
33
"@vocab": "http://example/",
4+
"@version": 1.1,
45
"B": {"@context": {"c": "http://example.org/c"}}
56
},
67
"a": {
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
require 'linkeddata'
2+
3+
graph = RDF::Graph.new
4+
graph << [RDF::URI("http://www.museum.com/fish"),
5+
RDF.type,
6+
RDF::URI("http://www.cidoc-crm.org/cidoc-crm/E55_Type")]
7+
8+
unframed_json = JSON::LD::API::fromRdf(graph)
9+
10+
11+
# Using this frame:
12+
frame = {
13+
"@context"=> [
14+
"https://linked.art/ns/context/1/full.jsonld",
15+
{"crm" => "http://www.cidoc-crm.org/cidoc-crm/"}
16+
]
17+
}
18+
19+
# This works
20+
puts JSON::LD::API.frame(unframed_json, frame, base: "http://www.example.com")
21+
22+
# But this doesn't.
23+
begin
24+
puts JSON::LD::API.frame(unframed_json, frame)
25+
rescue JSON::LD::JsonLdError::InvalidBaseIRI => e
26+
puts "This doesn't work: #{e}"
27+
end
28+
29+
30+
# But using this frame:
31+
frame = {
32+
"@context"=> [
33+
{"crm" => "http://www.cidoc-crm.org/cidoc-crm/"}
34+
]
35+
}
36+
# Both of these work
37+
puts JSON::LD::API.frame(unframed_json, frame, base: "http://www.example.com")
38+
puts JSON::LD::API.frame(unframed_json, frame)

lib/json/ld/compact.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,17 @@ def compact(element, property: nil)
101101
next
102102
end
103103

104+
if expanded_property == '@preserve'
105+
# Compact using `property`
106+
compacted_value = compact(expanded_value, property: property)
107+
#log_debug("@preserve") {"compacted_value: #{compacted_value.inspect}"}
108+
109+
unless compacted_value.is_a?(Array) && compacted_value.empty?
110+
result['@preserve'] = compacted_value
111+
end
112+
next
113+
end
114+
104115
if expanded_property == '@index' && context.container(property) == '@index'
105116
#log_debug("@index") {"drop @index"}
106117
next

lib/json/ld/context.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,6 +1023,9 @@ def compact_iri(iri, value: nil, vocab: nil, reverse: false, quiet: false, **opt
10231023
containers = []
10241024
tl, tl_value = "@language", "@null"
10251025

1026+
# If the value is a JSON Object with the key @preserve, use the value of @preserve.
1027+
value = value['@preserve'].first if value.is_a?(Hash) && value.has_key?('@preserve')
1028+
10261029
# If the value is a JSON Object, then for the keywords @index, @id, and @type, if the value contains that keyword, append it to containers.
10271030
%w(@index @id @type).each do |kw|
10281031
containers << kw if value.has_key?(kw)

lib/json/ld/expand.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,6 @@ def expand_object(input, active_property, context, output_object, ordered: false
384384

385385
# Initialize index value to the result of using this algorithm recursively, passing active context, key as active property, and index value as element.
386386
index_value = expand([value[k]].flatten, key, map_context, ordered: ordered)
387-
#require 'byebug'; byebug
388387
index_value.each do |item|
389388
case container
390389
when '@index' then item[container] ||= k

lib/json/ld/frame.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,11 +215,15 @@ def cleanup_preserve(input, bnodes_to_clear)
215215
result = case input
216216
when Array
217217
# If, after replacement, an array contains only the value null remove the value, leaving an empty array.
218-
input.map {|o| cleanup_preserve(o, bnodes_to_clear)}.compact
218+
v = input.map {|o| cleanup_preserve(o, bnodes_to_clear)}.compact
219+
220+
# If the array contains a single member, which is itself an array, use that value as the result
221+
v.length == 1 && v.first.is_a?(Array) ? v.first : v
219222
when Hash
220223
output = Hash.new
221224
input.each do |key, value|
222225
if key == '@preserve'
226+
#require 'byebug'; byebug
223227
# replace all key-value pairs where the key is @preserve with the value from the key-pair
224228
output = cleanup_preserve(value, bnodes_to_clear)
225229
elsif context.expand_iri(key) == '@id' && bnodes_to_clear.include?(value)

0 commit comments

Comments
 (0)