module JsonWalk
Module JsonWalk
written by Ph. Jounin Sept 2016 Released under GPL version 2
jsonwalk.rb
walk through a json tree. This is slighlty different from classical tree parsing since json nodes are either hashes, arrays or leaves
Constants
- VERBOSE
- VERSION
Public Class Methods
IsAncestor( root, nodes )
click to toggle source
return true if one member of nodes is descendant of the tree beginning by root probably useless outside the moduleā¦
# File lib/jsonwalk.rb, line 21 def JsonWalk.IsAncestor( root, nodes ) case root when Hash root.each do |k, v| return true if (nodes.include? v or IsAncestor(v, nodes)) end when Array root.each do |v| return true if (nodes.include? v or IsAncestor(v, nodes)) end else return true if (nodes.include? root) end return false end
backward(parent,node)
click to toggle source
move one step backward (but keep current selection)
# File lib/jsonwalk.rb, line 63 def JsonWalk.backward(parent,node) return nil if parent==nil or node==nil return parent.select { |child| IsAncestor(child, node) } end
forward(node, branch)
click to toggle source
move forward in the tree, if node is a hash return on child if it is an array, return the set of children
# File lib/jsonwalk.rb, line 40 def JsonWalk.forward(node, branch) # move forward : get the uniq child or all of them return nil if node==nil return node.kind_of?(Array) ? node.flatten.map {|child| child[branch]} : node[branch] end
select(node, branch, condition, operator)
click to toggle source
just select a set of children matching a condition this does not change the level in the tree
# File lib/jsonwalk.rb, line 48 def JsonWalk.select(node, branch, condition, operator) # check manually, seems less dangerous than using eval case operator when '==' return node.flatten.select {|child| child[branch]==condition} when '=~' return node.flatten.select {|child| /#{condition}/.match(child[branch])} when '!=' return node.flatten.select {|child| child[branch]!=condition} when '!~' return node.flatten.select {|child| not /#{condition}/.match(child[branch])} end end
walk(root, path)
click to toggle source
walk the json tree : root is the top of the tree returned by json.parse path is a list of keys to child nodes with either selection by value or backward steps
# File lib/jsonwalk.rb, line 71 def JsonWalk.walk(root, path) levels = [] # keep track of how do we get to the current node nodes = root path.each do |child_key| case child_key when Integer # just in case you want a fixed row print "moving forward to index #{child_key}\n" if VERBOSE nodes = (nodes.class==Array and child_key<nodes.count) ? nodes[child_key] : nil when '..' # move backwards, but keep only items which include a member of nodes in the sub tree print "moving one step backward\n" if VERBOSE nodes = backward(levels.pop, nodes) # levels.pop return the previous node when /(==|=~|!=|!~)/ # this is a selection, regexp returns before, after and matching substrings print "selecting nodes with key #{$`}, val #{$'}, cond #{$&}\n" if VERBOSE nodes = select( nodes, $`, $', $& ) else # move deeper in the tree print "moving forward to key #{child_key}\n" if VERBOSE levels.push nodes # keep track of current level nodes = forward( nodes, child_key) end end return nodes.class==Array ? nodes.compact : nodes end