Class: XML::XXPath
- Inherits:
-
Object
- Object
- XML::XXPath
- Defined in:
- lib/xml/xxpath.rb,
lib/xml/rexml_ext.rb,
lib/xml/xxpath/steps.rb
Overview
Instances of this class hold (in a pre-compiled form) an XPath pattern. You call instance methods like each, first, all, create_new on instances of this class to apply the pattern to REXML elements.
Defined Under Namespace
Modules: Accessors Classes: AllElementsStep, AlternativeNamesStep, AttrNameStep, AttrStep, NameAndAttrStep, NameAndIndexStep, NameStep, Step, TextNodesStep, ThisNodeStep
Instance Method Summary collapse
-
#all(node, options = {}) ⇒ Object
Return an Enumerable with all sub-nodes of node that match this XPath.
-
#create_new(base_node) ⇒ Object
create a completely new match of this XPath in base_node.
-
#each(node, options = {}, &block) ⇒ Object
loop over all sub-nodes of node that match this XPath.
-
#first(node, options = {}) ⇒ Object
the first sub-node of node that matches this XPath.
-
#initialize(xpathstr) ⇒ XXPath
constructor
create and compile a new XPath.
Constructor Details
#initialize(xpathstr) ⇒ XXPath
create and compile a new XPath. xpathstr is the string representation (XPath pattern) of the path
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 |
# File 'lib/xml/xxpath.rb', line 21 def initialize(xpathstr) @xpathstr = xpathstr # for error messages # TODO: write a real XPath parser sometime xpathstr='/'+xpathstr if xpathstr[0] != ?/ @creator_procs = [ proc{|node,create_new| node} ] @reader_proc = proc {|nodes| nodes} part=nil; part_expected=true xpathstr.split(/(\/+)/)[1..-1].reverse.each do |x| if part_expected part=x part_expected = false next end part_expected = true axis = case x when '/' :child when '//' :descendant else raise XXPathError, "XPath (#{xpathstr}): unknown axis: #{x}" end axis=:self if axis==:child and (part[0]==?. or part=~/^self::/) # yuck step = Step.compile(axis,part) @creator_procs << step.creator(@creator_procs[-1]) @reader_proc = step.reader(@reader_proc, @creator_procs[-1]) end end |
Instance Method Details
#all(node, options = {}) ⇒ Object
Return an Enumerable with all sub-nodes of node that match this XPath. Returns an empty Enumerable if no match was found.
If :ensure_created=>true is provided, all() ensures that a match exists in node, creating one (and returning it as the sole element of the returned enumerable) if none existed before.
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/xml/xxpath.rb', line 88 def all(node,={}) raise "options not a hash" unless Hash=== if [:create_new] return [ @creator_procs[-1].call(node,true) ] else last_nodes,rest_creator = catch(:not_found) do return @reader_proc.call([node]) end if [:ensure_created] [ rest_creator.call(last_nodes[0],false) ] else [] end end end |
#create_new(base_node) ⇒ Object
create a completely new match of this XPath in base_node. “Completely new” means that a new node will be created for each path element, even if a matching node already existed in base_node.
path.create_new(node) is equivalent to path.first(node,:create_new=>true).
111 112 113 |
# File 'lib/xml/xxpath.rb', line 111 def create_new(base_node) first(base_node,:create_new=>true) end |
#each(node, options = {}, &block) ⇒ Object
loop over all sub-nodes of node that match this XPath.
57 58 59 |
# File 'lib/xml/xxpath.rb', line 57 def each(node,={},&block) all(node,).each(&block) end |
#first(node, options = {}) ⇒ Object
the first sub-node of node that matches this XPath. If nothing matches, raise XXPathError unless :allow_nil=>true was provided.
If :ensure_created=>true is provided, first() ensures that a match exists in node, creating one if none existed before.
path.first(node,:create_new=>true) is equivalent to path.create_new(node).
69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/xml/xxpath.rb', line 69 def first(node,={}) a=all(node,) if a.empty? if [:allow_nil] nil else raise XXPathError, "path not found: #{@xpathstr}" end else a[0] end end |