class XPath::XPathNodeSet
Constants
- IteratorForAxis
Attributes
nodes[R]
Public Class Methods
def_comparison_operator(*ops)
click to toggle source
# File lib/xml/xpath.rb, line 2778 def self.def_comparison_operator(*ops) ops.each { |op| module_eval <<_, __FILE__, __LINE__ + 1 def #{op}(other) if other.is_a? XPathBoolean then other #{op} self.to_boolean else visitor = @visitor str = @context.make_string('') ret = false @nodes.each { |node| str.replace visitor.visit(node).string_value break if ret = (other #{op} str) } ret end end _ } end
new(context, *nodes)
click to toggle source
# File lib/xml/xpath.rb, line 2746 def initialize(context, *nodes) @context = context.dup @visitor = context.visitor nodes.sort! { |a,b| compare_position a, b } @nodes = nodes end
Public Instance Methods
**(other)
click to toggle source
Calls superclass method
XPath::XPathObject#**
# File lib/xml/xpath.rb, line 2805 def **(other) super unless other.is_a? XPathNodeSet merge other.nodes self end
at(pos)
click to toggle source
# File lib/xml/xpath.rb, line 2997 def at(pos) n = pos.to_i if n != pos or n <= 0 then node = nil else node = @nodes[n - 1] end @nodes.clear @nodes.push node if node self end
count()
click to toggle source
# File lib/xml/xpath.rb, line 2812 def count @nodes.size end
each(&block)
click to toggle source
# File lib/xml/xpath.rb, line 2820 def each(&block) @nodes.each(&block) end
first()
click to toggle source
# File lib/xml/xpath.rb, line 2816 def first @nodes[0] end
funcall(name) { |c| ... }
click to toggle source
Calls superclass method
XPath::XPathObject#funcall
# File lib/xml/xpath.rb, line 2825 def funcall(name) # for XPointer raise "BUG" unless block_given? func = ('f_' + name.tr('-', '_')).intern super unless respond_to? func, true size = @nodes.size pos = 1 c = @context.dup begin @nodes.collect! { |node| c.reuse node, pos, size pos += 1 args = yield(c) send(func, node, *args) } rescue Object::ArgumentError if $@[1] == "#{__FILE__}:#{__LINE__-3}:in `send'" then raise XPath::ArgumentError, "#{$!} for `#{name}'" end raise end self end
predicate() { |context| ... }
click to toggle source
# File lib/xml/xpath.rb, line 2976 def predicate context = @context size = @nodes.size pos = 1 result = nil newnodes = @nodes.reject { |node| context.reuse node, pos, size pos += 1 result = yield(context) break if result.is_a? Numeric not result } if result.is_a? Numeric then at result else @nodes = newnodes end self end
select_all(axis)
click to toggle source
# File lib/xml/xpath.rb, line 2961 def select_all(axis) iterator = get_iterator(axis) visitor = @visitor oldnodes = @nodes @nodes = [] oldnodes.each { |start| nodes = [] iterator.each(start, visitor) { |i| nodes.push i.node } nodes.reverse! if iterator.reverse_order? merge nodes } self end
step(axis) { |lstep| ... }
click to toggle source
# File lib/xml/xpath.rb, line 2945 def step(axis) iterator = get_iterator(axis) lstep = make_location_step lstep.set_iterator iterator oldnodes = @nodes @nodes = [] oldnodes.each { |node| lstep.reuse node nodes = yield(lstep).nodes nodes.reverse! if iterator.reverse_order? merge nodes } self end
to_f()
click to toggle source
# File lib/xml/xpath.rb, line 2765 def to_f to_string(@context).to_f end
to_ruby()
click to toggle source
# File lib/xml/xpath.rb, line 2773 def to_ruby @nodes end
to_str()
click to toggle source
# File lib/xml/xpath.rb, line 2757 def to_str if @nodes.empty? then '' else @visitor.visit(@nodes[0]).string_value end end
true?()
click to toggle source
# File lib/xml/xpath.rb, line 2769 def true? not @nodes.empty? end
Private Instance Methods
compare_position(node1, node2)
click to toggle source
# File lib/xml/xpath.rb, line 2851 def compare_position(node1, node2) visitor = @visitor ancestors1 = [] ancestors2 = [] p1 = visitor.visit(node1).parent while p1 ancestors1.push node1 p1 = visitor.visit(node1 = p1).parent end p2 = visitor.visit(node2).parent while p2 ancestors2.push node2 p2 = visitor.visit(node2 = p2).parent end unless node1 == node2 then raise XPath::Error, "can't compare the positions of given two nodes" end n = -1 ancestors1.reverse_each { |node1| node2 = ancestors2[n] unless node1 == node2 then break unless node2 return visitor.visit(node1).index - visitor.visit(node2).index end n -= 1 } ancestors1.size - ancestors2.size end
get_iterator(axis)
click to toggle source
# File lib/xml/xpath.rb, line 2926 def get_iterator(axis) ret = IteratorForAxis[axis] unless ret then raise XPath::NameError, "invalid axis `#{axis.id2name.tr('_','-')}'" end ret end
make_location_step()
click to toggle source
# File lib/xml/xpath.rb, line 2934 def make_location_step if defined? @__lstep__ then @__lstep__ else @__lstep__ = LocationStep.new(@context) end end
merge(other)
click to toggle source
# File lib/xml/xpath.rb, line 2881 def merge(other) if @nodes.empty? or other.empty? then @nodes.concat other elsif (n = compare_position(@nodes.last, other.first)) <= 0 then @nodes.pop if n == 0 @nodes.concat other elsif (n = compare_position(other.last, @nodes.first)) <= 0 then other.pop if n == 0 @nodes = other.concat(@nodes) else newnodes = [] nodes = @nodes until nodes.empty? or other.empty? n = compare_position(nodes.last, other.last) if n > 0 then newnodes.push nodes.pop elsif n < 0 then newnodes.push other.pop else newnodes.push nodes.pop other.pop end end newnodes.reverse! @nodes.concat(other).concat(newnodes) end end