1 2 3 4 5 6 7 8 9 10 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
|
## -*- Ruby -*-
## XML::SimpleTree::Visitor
## 1998 by yoshidam
##
## Oct 23, 1998 yoshidam Fix each
##
module XML
module SimpleTree
## Skeleton visitor
class Visitor
## You can override the following methods and implement the other
## "visit_TYPE" methods.
## You should implement some "visit_name_NAME" methods and
## "method_missing" method for accept_name.
def visit_Document(grove, *rest)
grove.children_accept(self, *rest)
end
def visit_Element(element, *rest)
element.children_accept(self, *rest)
end
def visit_Text(text, *rest)
end
def visit_CDATASection(text, *rest)
end
def visit_Comment(comment, *rest)
end
def visit_ProcessingInstruction(pi, *rest)
end
end
class Node
## XML::Grove::Visitor like interfaces
def accept(visitor, *rest)
typename = type.to_s.sub!(/.*?([^:]+)$/, '\1')
visitor.send("visit_" + typename, self, *rest)
end
def accept_name(visitor, *rest)
if nodeType == ELEMENT
name_method = "visit_name_" + nodeName
visitor.send(name_method, self, *rest)
else
self.accept(visitor, *rest)
end
end
def children_accept(visitor, *rest)
ret = []
@children && @children.each { |node|
ret.push(node.accept(visitor, *rest))
}
ret
end
def children_accept_name(visitor, *rest)
ret = []
@children && @children.each { |node|
ret.push(node.accept_name(visitor, *rest))
}
ret
end
## Iterator interface
include Enumerable
def each
sibstack = []
siblings = [ self ]
while true
if siblings.length == 0
break if sibstack.length == 0
siblings = sibstack.pop
next
end
node = siblings.shift
yield(node)
children = node.childNodes
if !children.nil?
sibstack.push(siblings)
siblings = children.to_a.dup
end
end
end
end
end
end
|