File: xmltreevisitor.rb

package info (click to toggle)
libxml-parser-ruby 0.5.16-1
  • links: PTS
  • area: main
  • in suites: potato
  • size: 596 kB
  • ctags: 702
  • sloc: ruby: 4,474; ansic: 1,254; xml: 542; makefile: 53
file content (96 lines) | stat: -rw-r--r-- 2,172 bytes parent folder | download
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