Module: JsonWalk
- Defined in:
- lib/jsonwalk.rb,
lib/jsonwalk/version.rb
Overview
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
Constant Summary collapse
- VERBOSE =
traces ?
false- VERSION =
"1.1.2"
Class Method Summary collapse
-
.backward(parent, node) ⇒ Object
move one step backward (but keep current selection).
-
.forward(node, branch) ⇒ Object
move forward in the tree, if node is a hash return on child if it is an array, return the set of children.
-
.IsAncestor(root, nodes) ⇒ Object
return true if one member of nodes is descendant of the tree beginning by root probably useless outside the module…
-
.select(node, branch, condition, operator) ⇒ Object
just select a set of children matching a condition this does not change the level in the tree.
-
.walk(root, path) ⇒ Object
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.
Class Method Details
.backward(parent, node) ⇒ Object
move one step backward (but keep current selection)
63 64 65 66 |
# 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) ⇒ Object
move forward in the tree, if node is a hash return on child if it is an array, return the set of children
40 41 42 43 44 |
# 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 |
.IsAncestor(root, nodes) ⇒ Object
return true if one member of nodes is descendant of the tree beginning by root probably useless outside the module…
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# 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 |
.select(node, branch, condition, operator) ⇒ Object
just select a set of children matching a condition this does not change the level in the tree
48 49 50 51 52 53 54 55 56 57 58 59 60 |
# 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) ⇒ Object
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
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 |
# 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 |