Class: REXML::Parsers::XPathParser
- Inherits:
-
Object
- Object
- REXML::Parsers::XPathParser
- Includes:
- XMLTokens
- Defined in:
- lib/rexml/parsers/xpathparser.rb
Overview
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!
Constant Summary collapse
- LITERAL =
/^'([^']*)'|^"([^"]*)"/u
Constants included from XMLTokens
XMLTokens::NAME, XMLTokens::NAMECHAR, XMLTokens::NAME_CHAR, XMLTokens::NAME_START_CHAR, XMLTokens::NAME_STR, XMLTokens::NCNAME_STR, XMLTokens::NMTOKEN, XMLTokens::NMTOKENS, XMLTokens::REFERENCE
Instance Method Summary collapse
- #abbreviate(path_or_parsed) ⇒ Object
- #expand(path_or_parsed) ⇒ Object
- #namespaces=(namespaces) ⇒ Object
- #parse(path) ⇒ Object
- #predicate(path) ⇒ Object
- #predicate_to_path(parsed, &block) ⇒ Object (also: #preciate_to_string)
Instance Method Details
#abbreviate(path_or_parsed) ⇒ Object
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 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 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# 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) ⇒ Object
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/rexml/parsers/xpathparser.rb', line 132 def (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| (x) } path << ']' when :document document = true else path << "UNKNOWN(" path << op.inspect path << ")" end end path = "/"+path if document path end |
#namespaces=(namespaces) ⇒ Object
16 17 18 19 |
# File 'lib/rexml/parsers/xpathparser.rb', line 16 def namespaces=( namespaces ) Functions::namespace_context = namespaces @namespaces = namespaces end |
#parse(path) ⇒ Object
21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# 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) ⇒ Object
36 37 38 39 40 |
# File 'lib/rexml/parsers/xpathparser.rb', line 36 def predicate path parsed = [] Predicate( "[#{path}]", parsed ) parsed end |
#predicate_to_path(parsed, &block) ⇒ Object Also known as: preciate_to_string
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# 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 |