YAML Generic Model container
We want the node to act like as Hash if it is.
# File yaml/basenode.rb, line 185 def []( *key ) if Hash === @value v = @value.detect { |k,| k.transform == key.first } v[1] if v elsif Array === @value @value.[]( *key ) end end
# File yaml/basenode.rb, line 69 def at( seg ) if Hash === @value self[seg] elsif Array === @value and seg =~ /\A\d+\Z/ and @value[seg.to_i] @value[seg.to_i] end end
# File yaml/basenode.rb, line 194 def children if Hash === @value @value.values.collect { |c| c[1] } elsif Array === @value @value end end
# File yaml/basenode.rb, line 202 def children_with_index if Hash === @value @value.keys.collect { |i| [self[i], i] } elsif Array === @value i = -1; @value.collect { |v| i += 1; [v, i] } end end
YPath search returning a complete depth array
# File yaml/basenode.rb, line 80 def match_path( ypath_str ) depth = 0 matches = [] YPath.each_path( ypath_str ) do |ypath| seg = match_segment( ypath, 0 ) matches += seg if seg end matches.uniq end
Search a node for a single YPath segment
# File yaml/basenode.rb, line 93 def match_segment( ypath, depth ) deep_nodes = [] seg = ypath.segments[ depth ] if seg == "/" unless String === @value idx = -1 @value.collect { |v| idx += 1 if Hash === @value match_init = [v[0].transform, v[1]] match_deep = v[1].match_segment( ypath, depth ) else match_init = [idx, v] match_deep = v.match_segment( ypath, depth ) end if match_deep match_deep.each { |m| deep_nodes.push( match_init + m ) } end } end depth += 1 seg = ypath.segments[ depth ] end match_nodes = case seg when "." [[nil, self]] when ".." [["..", nil]] when "*" if @value.is_a? Enumerable idx = -1 @value.collect { |h| idx += 1 if Hash === @value [h[0].transform, h[1]] else [idx, h] end } end else if seg =~ /^"(.*)"$/ seg = $1 elsif seg =~ /^'(.*)'$/ seg = $1 end if ( v = at( seg ) ) [[ seg, v ]] end end return deep_nodes unless match_nodes pred = ypath.predicates[ depth ] if pred case pred when /^\.=/ pred = $' # ' match_nodes.reject! { |n| n.last.value != pred } else match_nodes.reject! { |n| n.last.at( pred ).nil? } end end return match_nodes + deep_nodes unless ypath.segments.length > depth + 1 #puts "DEPTH: #{depth + 1}" deep_nodes = [] match_nodes.each { |n| if n[1].is_a? BaseNode match_deep = n[1].match_segment( ypath, depth + 1 ) if match_deep match_deep.each { |m| deep_nodes.push( n + m ) } end else deep_nodes = [] end } deep_nodes = nil if deep_nodes.length == 0 deep_nodes end
Search for YPath entry and return a list of qualified paths.
# File yaml/basenode.rb, line 55 def search( ypath_str ) matches = match_path( ypath_str ) if matches matches.collect { |m| path = [] m.each_index { |i| path.push m[i] if ( i % 2 ).zero? } "/" + path.compact.join( "/" ) } end end
Search for YPath entry and return qualified nodes.
# File yaml/basenode.rb, line 17 def select( ypath_str ) matches = match_path( ypath_str ) # # Create a new generic view of the elements selected # if matches result = [] matches.each { |m| result.push m.last } YAML.transfer( 'seq', result ) end end
Search for YPath entry and return transformed nodes.
# File yaml/basenode.rb, line 36 def select!( ypath_str ) matches = match_path( ypath_str ) # # Create a new generic view of the elements selected # if matches result = [] matches.each { |m| result.push m.last.transform } result end end