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 127 128 129 130 131 |
# 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 && @options[:compactArrays] 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 with all null values removed. # If there already exists a value for active property in element and the full IRI of property is also coerced to @list, return an error. # FIXME: check for full-iri list coercion # Otherwise store the resulting array as value of active property if empty or property otherwise. 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) position = key == '@id' ? :subject : :type 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 => position, :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 => position, :depth => @depth)} debug {" => compacted value(#{key}): #{compacted_value.inspect}"} compacted_value = compacted_value.first if compacted_value.length == 1 && @options[:compactArrays] 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 |