Module: LibXML::XML::XPath

Defined in:
lib/rmtools/xml/xpath.rb

Defined Under Namespace

Classes: Object

Constant Summary collapse

Finders =
{}

Class Method Summary collapse

Class Method Details

.filter(xpath) ⇒ Object



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
# File 'lib/rmtools/xml/xpath.rb', line 7

def self.filter(xpath)
  xpath = xpath.strip
  return xpath[1..-1] if xpath[0] == ?!
  if x = Finders[xpath]; return x end
  if xpath[%r{\[@?\w+([^\w!]=).+?\]}]
    raise XML::Error, "can't process '#{$1}' operator"
  end
  x = xpath.dup
  x.gsub! %r{([^\\]|\A)\s*>\s*}, '\1/'
  x.gsub! %r{([^\\])\s+}, '\1//'
  x.gsub! %r{(\.([\w-]+))+(?=[\[\{/]|\Z)} do |m| "[@class=\"#{m.split('.')[1..-1]*' '}\"]" end
  x.gsub! %r{#([\w-]+)([\[\{/.]|\Z)}, '[@id="\1"]\2'
  x.gsub! %r{(^|/)([^.#\w*/'"])}, '\1*\2'
  x.gsub! %r{\[([a-z]+)}, '[@\1'
  x.gsub! %r{(\[(?:@\w+!?=)?)['"]?([^'"\]@]+)['"]?\]}, '\1"\2"]'
  if x !~%r{^(?:#{
                  }(?:\./|\.//|/|//)?#{
                  }(?:(?:[\w\-]+:)?[\w\-]+|\*)#{                         #  [ns:]name
                  }(?:\[(?:@\w+(!?="[^"]+")?|"[^"]+")\])*#{#  attributes [@href!="pics/xynta.jpeg"]
                  }(?:\[-?\d+\]|\{[^\}]+\})?#{               #  inruby-filters (see finder functions ^)
                  })+$}
    raise XML::Error, "can't process `#{xpath}`; #{x}" 
  end
  x = '//'+x if x !~ %r{^[./]}
  x.sub! %r{^/}, './'
  Finders[xpath] = x
end