Module: JSON::LD::Compact
Instance Method Summary collapse
-
#compact(element, property = nil) ⇒ Array, Hash
Compact an expanded Array or Hash given an active property and a context.
Methods included from Utils
#blank_node?, #list?, #node?, #node_reference?, #value?
Instance Method Details
#compact(element, property = nil) ⇒ Array, Hash
Compact an expanded Array or Hash given an active property and a context.
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 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 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/json/ld/compact.rb', line 11 def compact(element, property = nil) if property.nil? debug("compact") {"element: #{element.inspect}, ec: #{context.inspect}"} else debug("compact") {"property: #{property.inspect}"} end case element when Array # 1) If value is an array, process each item in value recursively using # this algorithm, passing copies of the active context and the # active property. debug("compact") {"Array #{element.inspect}"} result = depth {element.map {|v| compact(v, property)}} # If element has a single member and the active property has no # @container mapping to @list or @set, the compacted value is that # member; otherwise the compacted value is element if result.length == 1 debug("=> extract single element: #{result.first.inspect}") result.first else debug("=> array result: #{result.inspect}") result end when Hash # 2) Otherwise, if element is an object: result = {} if k = %w(@list @set @value).detect {|container| element.has_key?(container)} debug("compact") {"#{k}: container(#{property}) = #{context.container(property)}"} end k ||= '@id' if element.keys == ['@id'] case k when '@value', '@id' # If element has an @value property or element is a node reference, return the result of performing # Value Compaction on element using active property. v = context.compact_value(property, element, :depth => @depth) debug("compact") {"value optimization, return as #{v.inspect}"} return v when '@list' # Otherwise, if the active property has a @container mapping to @list and element has a corresponding @list property, recursively compact that property's value passing a copy of the active context and the active property ensuring that the result is an array and removing null values. compacted_key = context.compact_iri(k, :position => :predicate, :depth => @depth) v = depth { compact(element[k], property) } # Return either the result as an array, as an object with a key of @list (or appropriate alias from active context v = [v].compact unless v.is_a?(Array) v = {compacted_key => v} unless context.container(property) == k debug("compact") {"@list result, return as #{v.inspect}"} return v end # Otherwise, for each property and value in element: element.each do |key, value| debug("compact") {"#{key}: #{value.inspect}"} if %(@id @type).include?(key) compacted_key = context.compact_iri(key, :position => :predicate, :depth => @depth) result[compacted_key] = case value when String # If value is a string, the compacted value is the result of performing IRI Compaction on value. debug {" => compacted string for #{key}"} context.compact_iri(value, :position => :subject, :depth => @depth) when Array # Otherwise, value must be an array. Perform IRI Compaction on every entry of value. If value contains just one entry, value is set to that entry compacted_value = value.map {|v| context.compact_iri(v, :position => :subject, :depth => @depth)} debug {" => compacted value(#{key}): #{compacted_value.inspect}"} compacted_value = compacted_value.first if compacted_value.length == 1 compacted_value end else if value.empty? # Make sure that an empty array is preserved compacted_key = context.compact_iri(key, :position => :predicate, :depth => @depth) next if compacted_key.nil? result[compacted_key] = value end # For each item in value: raise ProcessingError, "found #{value.inspect} for #{key} if #{element.inspect}" unless value.is_a?(Array) value.each do |item| compacted_key = context.compact_iri(key, :position => :predicate, :value => item, :depth => @depth) debug {" => compacted key: #{compacted_key.inspect} for #{item.inspect}"} next if compacted_key.nil? compacted_item = depth {self.compact(item, compacted_key)} debug {" => compacted value: #{compacted_value.inspect}"} case result[compacted_key] when Array result[compacted_key] << compacted_item when nil if !compacted_value.is_a?(Array) && context.container(compacted_key) == '@set' compacted_item = [compacted_item].compact debug {" => as @set: #{compacted_item.inspect}"} end result[compacted_key] = compacted_item else result[compacted_key] = [result[compacted_key], compacted_item] end end end end # Re-order result keys r = Hash.ordered result.keys.sort.each {|k| r[k] = result[k]} r else # For other types, the compacted value is the element value debug("compact") {element.class.to_s} element end end |