class REXML::Parsers::XPathParser
You don’t want to use this class. Really. Use XPath
, which is a wrapper for this class. Believe me. You don’t want to poke around in here. There is strange, dark magic at work in this code. Beware. Go back! Go back while you still can!
Constants
- AXIS
RelativeLocationPath
| Step | (AXIS_NAME '::' | '@' | '') AxisSpecifier NodeTest Predicate | '.' | '..' AbbreviatedStep | RelativeLocationPath '/' Step | RelativeLocationPath '//' Step
- LITERAL
- LOCAL_NAME_WILDCARD
- NODE_TYPE
- NT
- NUMBER
- PI
- PREFIX_WILDCARD
Returns a 1-1 map of the nodeset The contents of the resulting array are either: true/false, if a positive match String, if a name match
NodeTest
| ('*' | NCNAME ':' '*' | QNAME) NameTest | '*' ':' NCNAME NameTest since XPath 2.0 | NODE_TYPE '(' ')' NodeType | PI '(' LITERAL ')' PI | '[' expr ']' Predicate
- QNAME
- VARIABLE_REFERENCE
|
VARIABLE_REFERENCE
| ‘(’ expr ‘)’ |LITERAL
|NUMBER
| FunctionCall
Public Instance Methods
abbreviate(path_or_parsed)
click to toggle source
# File lib/rexml/parsers/xpathparser.rb, line 42 def abbreviate(path_or_parsed) if path_or_parsed.kind_of?(String) parsed = parse(path_or_parsed) else parsed = path_or_parsed end components = [] component = nil while parsed.size > 0 op = parsed.shift case op when :node component << "node()" when :attribute component = "@" components << component when :child component = "" components << component when :descendant_or_self next_op = parsed[0] if next_op == :node parsed.shift component = "" components << component else component = "descendant-or-self::" components << component end when :self next_op = parsed[0] if next_op == :node parsed.shift components << "." else component = "self::" components << component end when :parent next_op = parsed[0] if next_op == :node parsed.shift components << ".." else component = "parent::" components << component end when :any component << "*" when :text component << "text()" when :following, :following_sibling, :ancestor, :ancestor_or_self, :descendant, :namespace, :preceding, :preceding_sibling component = op.to_s.tr("_", "-") << "::" components << component when :qname prefix = parsed.shift name = parsed.shift component << prefix+":" if prefix.size > 0 component << name when :predicate component << '[' component << predicate_to_path(parsed.shift) {|x| abbreviate(x)} component << ']' when :document components << "" when :function component << parsed.shift component << "( " component << predicate_to_path(parsed.shift[0]) {|x| abbreviate(x)} component << " )" when :literal component << quote_literal(parsed.shift) else component << "UNKNOWN(" component << op.inspect component << ")" end end case components when [""] "/" when ["", ""] "//" else components.join("/") end end
expand(path_or_parsed)
click to toggle source
# File lib/rexml/parsers/xpathparser.rb, line 132 def expand(path_or_parsed) if path_or_parsed.kind_of?(String) parsed = parse(path_or_parsed) else parsed = path_or_parsed end path = "" document = false while parsed.size > 0 op = parsed.shift case op when :node path << "node()" when :attribute, :child, :following, :following_sibling, :ancestor, :ancestor_or_self, :descendant, :descendant_or_self, :namespace, :preceding, :preceding_sibling, :self, :parent path << "/" unless path.size == 0 path << op.to_s.tr("_", "-") path << "::" when :any path << "*" when :qname prefix = parsed.shift name = parsed.shift path << prefix+":" if prefix.size > 0 path << name when :predicate path << '[' path << predicate_to_path( parsed.shift ) { |x| expand(x) } path << ']' when :document document = true else path << "UNKNOWN(" path << op.inspect path << ")" end end path = "/"+path if document path end
namespaces=( namespaces )
click to toggle source
# File lib/rexml/parsers/xpathparser.rb, line 16 def namespaces=( namespaces ) Functions::namespace_context = namespaces @namespaces = namespaces end
parse(path)
click to toggle source
# File lib/rexml/parsers/xpathparser.rb, line 21 def parse path path = path.dup path.gsub!(/([\(\[])\s+/, '\1') # Strip ignorable spaces path.gsub!( /\s+([\]\)])/, '\1') parsed = [] rest = OrExpr(path, parsed) if rest unless rest.strip.empty? raise ParseException.new("Garbage component exists at the end: " + "<#{rest}>: <#{path}>") end end parsed end
predicate(path)
click to toggle source
# File lib/rexml/parsers/xpathparser.rb, line 36 def predicate path parsed = [] Predicate( "[#{path}]", parsed ) parsed end
predicate_to_path(parsed) { |parsed| ... }
click to toggle source
# File lib/rexml/parsers/xpathparser.rb, line 174 def predicate_to_path(parsed, &block) path = "" case parsed[0] when :and, :or, :mult, :plus, :minus, :neq, :eq, :lt, :gt, :lteq, :gteq, :div, :mod, :union op = parsed.shift case op when :eq op = "=" when :lt op = "<" when :gt op = ">" when :lteq op = "<=" when :gteq op = ">=" when :neq op = "!=" when :union op = "|" end left = predicate_to_path( parsed.shift, &block ) right = predicate_to_path( parsed.shift, &block ) path << left path << " " path << op.to_s path << " " path << right when :function parsed.shift name = parsed.shift path << name path << "(" parsed.shift.each_with_index do |argument, i| path << ", " if i > 0 path << predicate_to_path(argument, &block) end path << ")" when :literal parsed.shift path << quote_literal(parsed.shift) else path << yield( parsed ) end return path.squeeze(" ") end
Also aliased as: preciate_to_string