Class: Taurus::XML::NodeSet
- Inherits:
-
Object
- Object
- Taurus::XML::NodeSet
show all
- Includes:
- Enumerable, Searchable
- Defined in:
- lib/taurus/xml/node_set.rb
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
Methods included from Searchable
#at, #at_css, #at_xpath, #css, #search
Constructor Details
#initialize(document, source = nil) ⇒ NodeSet
Two construction modes:
- eager: pass an Array of Nodes (e.g. Element#children builds one)
- lazy: pass an FFI::Pointer to a TaurusXPathResult that this NodeSet
will keep alive and free on GC. Each [i] / each call goes
through taurus_xpath_result_get instead of pre-materializing.
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
# File 'lib/taurus/xml/node_set.rb', line 16
def initialize(document, source = nil)
@document = document
case source
when ::FFI::Pointer
if source.null?
@result_ptr = nil
@array = []
else
@result_ptr = ::FFI::AutoPointer.new(source, Taurus::XML::FFI.method(:taurus_xpath_result_free))
@array = nil
end
when nil
@result_ptr = nil
@array = []
else
@result_ptr = nil
@array = source.to_a
end
end
|
Instance Attribute Details
#document ⇒ Object
Returns the value of attribute document.
9
10
11
|
# File 'lib/taurus/xml/node_set.rb', line 9
def document
@document
end
|
Class Method Details
.from_result(document, result_ptr) ⇒ Object
39
40
41
|
# File 'lib/taurus/xml/node_set.rb', line 39
def self.from_result(document, result_ptr)
new(document, result_ptr)
end
|
Instance Method Details
#[](idx) ⇒ Object
52
53
54
55
56
57
58
59
60
61
|
# File 'lib/taurus/xml/node_set.rb', line 52
def [](idx)
if @result_ptr
return nil if idx < 0 || idx >= length
ptr = Taurus::XML::FFI.taurus_xpath_result_get(@result_ptr, idx)
return nil if ptr.null?
Taurus::XML::Node.wrap(ptr, @document)
else
@array[idx]
end
end
|
#each ⇒ Object
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
|
# File 'lib/taurus/xml/node_set.rb', line 63
def each
return enum_for(:each) unless block_given?
if @result_ptr
n = length
if n > 0
buf = ::FFI::MemoryPointer.new(:pointer, n)
begin
copied = Taurus::XML::FFI.taurus_xpath_result_get_nodes(@result_ptr, buf, n)
copied.times do |i|
ptr = buf.get_pointer(i * ::FFI.type_size(:pointer))
next if ptr.null?
yield Taurus::XML::Node.wrap(ptr, @document)
end
ensure
buf.free
end
end
else
@array.each { |n| yield n }
end
self
end
|
#empty? ⇒ Boolean
48
49
50
|
# File 'lib/taurus/xml/node_set.rb', line 48
def empty?
length == 0
end
|
#first(n = nil) ⇒ Object
100
101
102
103
|
# File 'lib/taurus/xml/node_set.rb', line 100
def first(n = nil)
return self[0] if n.nil?
n.times.map { |i| self[i] }.take_while { |x| !x.nil? }
end
|
#inner_text ⇒ Object
Also known as:
text
113
114
115
|
# File 'lib/taurus/xml/node_set.rb', line 113
def inner_text
map(&:content).join
end
|
#inspect ⇒ Object
134
135
136
|
# File 'lib/taurus/xml/node_set.rb', line 134
def inspect
to_a.inspect
end
|
#last ⇒ Object
105
106
107
108
109
110
111
|
# File 'lib/taurus/xml/node_set.rb', line 105
def last
if @result_ptr
self[length - 1]
else
@array.last
end
end
|
#length ⇒ Object
Also known as:
size
43
44
45
|
# File 'lib/taurus/xml/node_set.rb', line 43
def length
@result_ptr ? Taurus::XML::FFI.taurus_xpath_result_count(@result_ptr) : @array.length
end
|
#to_a ⇒ Object
Also known as:
to_ary
90
91
92
93
94
95
96
97
|
# File 'lib/taurus/xml/node_set.rb', line 90
def to_a
return @array if @array
return [] if @result_ptr.nil?
out = []
each { |n| out << n }
@array = out out
end
|
#xpath(*paths) ⇒ Object
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
# File 'lib/taurus/xml/node_set.rb', line 118
def xpath(*paths)
handler, _ns, _vars = parse_search_args(paths)
raise ArgumentError, "custom XPath handlers not supported" if handler
expr = paths.join(" | ")
accumulated = Taurus::XML::NodeSet.new(@document)
each do |node|
next unless node.is_a?(Taurus::XML::Element)
result_ptr = Taurus::XML::FFI.taurus_xpath_eval(
@document.c_ptr, node.c_ptr, expr)
next if result_ptr.null?
sub = Taurus::XML::NodeSet.send(:from_result, @document, result_ptr)
accumulated = merge_node_sets(accumulated, sub)
end
accumulated
end
|