| Class | REXML::Parsers::XPathParser |
| In: |
|
| Parent: | Object |
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!
Included Modules
Constants
| LITERAL | = | /^'([^']*)'|^"([^"]*)"/u | ||
| AXIS | = | /^(ancestor|ancestor-or-self|attribute|child|descendant|descendant-or-self|following|following-sibling|namespace|parent|preceding|preceding-sibling|self)::/ |
RelativeLocationPath
| Step
| (AXIS_NAME '::' | '@' | '') AxisSpecifier
NodeTest
Predicate
| '.' | '..' AbbreviatedStep
| RelativeLocationPath '/' Step
| RelativeLocationPath '//' Step
|
|
| NCNAMETEST | = | /^(#{NCNAME_STR}):\*/u | 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 matchNodeTest
| ('*' | NCNAME ':' '*' | QNAME) NameTest
| NODE_TYPE '(' ')' NodeType
| PI '(' LITERAL ')' PI
| '[' expr ']' Predicate
|
|
| QNAME | = | Namespace::NAMESPLIT | ||
| NODE_TYPE | = | /^(comment|text|node)\(\s*\)/m | ||
| PI | = | /^processing-instruction\(/ | ||
| VARIABLE_REFERENCE | = | /^\$(#{NAME_STR})/u | | VARIABLE_REFERENCE | ’(’ expr ’)’ | LITERAL | NUMBER | FunctionCall | |
| NUMBER | = | /^(\d*\.?\d+)/ | ||
| NT | = | /^comment|text|processing-instruction|node$/ |
Public Instance methods
33: def abbreviate( path ) 34: path = path.kind_of?(String) ? parse( path ) : path 35: string = "" 36: document = false 37: while path.size > 0 38: op = path.shift 39: case op 40: when :node 41: when :attribute 42: string << "/" if string.size > 0 43: string << "@" 44: when :child 45: string << "/" if string.size > 0 46: when :descendant_or_self 47: string << "/" 48: when :self 49: string << "." 50: when :parent 51: string << ".." 52: when :any 53: string << "*" 54: when :text 55: string << "text()" 56: when :following, :following_sibling, 57: :ancestor, :ancestor_or_self, :descendant, 58: :namespace, :preceding, :preceding_sibling 59: string << "/" unless string.size == 0 60: string << op.to_s.tr("_", "-") 61: string << "::" 62: when :qname 63: prefix = path.shift 64: name = path.shift 65: string << prefix+":" if prefix.size > 0 66: string << name 67: when :predicate 68: string << '[' 69: string << predicate_to_string( path.shift ) {|x| abbreviate( x ) } 70: string << ']' 71: when :document 72: document = true 73: when :function 74: string << path.shift 75: string << "( " 76: string << predicate_to_string( path.shift[0] ) {|x| abbreviate( x )} 77: string << " )" 78: when :literal 79: string << %Q{ "#{path.shift}" } 80: else 81: string << "/" unless string.size == 0 82: string << "UNKNOWN(" 83: string << op.inspect 84: string << ")" 85: end 86: end 87: string = "/"+string if document 88: return string 89: end
91: def expand( path ) 92: path = path.kind_of?(String) ? parse( path ) : path 93: string = "" 94: document = false 95: while path.size > 0 96: op = path.shift 97: case op 98: when :node 99: string << "node()" 100: when :attribute, :child, :following, :following_sibling, 101: :ancestor, :ancestor_or_self, :descendant, :descendant_or_self, 102: :namespace, :preceding, :preceding_sibling, :self, :parent 103: string << "/" unless string.size == 0 104: string << op.to_s.tr("_", "-") 105: string << "::" 106: when :any 107: string << "*" 108: when :qname 109: prefix = path.shift 110: name = path.shift 111: string << prefix+":" if prefix.size > 0 112: string << name 113: when :predicate 114: string << '[' 115: string << predicate_to_string( path.shift ) { |x| expand(x) } 116: string << ']' 117: when :document 118: document = true 119: else 120: string << "/" unless string.size == 0 121: string << "UNKNOWN(" 122: string << op.inspect 123: string << ")" 124: end 125: end 126: string = "/"+string if document 127: return string 128: end
14: def namespaces=( namespaces ) 15: Functions::namespace_context = namespaces 16: @namespaces = namespaces 17: end
19: def parse path 20: path.gsub!(/([\(\[])\s+/, '\1') # Strip ignorable spaces 21: path.gsub!( /\s+([\]\)])/, '\1' ) 22: parsed = [] 23: path = OrExpr(path, parsed) 24: parsed 25: end
130: def predicate_to_string( path, &block ) 131: string = "" 132: case path[0] 133: when :and, :or, :mult, :plus, :minus, :neq, :eq, :lt, :gt, :lteq, :gteq, :div, :mod, :union 134: op = path.shift 135: case op 136: when :eq 137: op = "=" 138: when :lt 139: op = "<" 140: when :gt 141: op = ">" 142: when :lteq 143: op = "<=" 144: when :gteq 145: op = ">=" 146: when :neq 147: op = "!=" 148: when :union 149: op = "|" 150: end 151: left = predicate_to_string( path.shift, &block ) 152: right = predicate_to_string( path.shift, &block ) 153: string << " " 154: string << left 155: string << " " 156: string << op.to_s 157: string << " " 158: string << right 159: string << " " 160: when :function 161: path.shift 162: name = path.shift 163: string << name 164: string << "( " 165: string << predicate_to_string( path.shift, &block ) 166: string << " )" 167: when :literal 168: path.shift 169: string << " " 170: string << path.shift.inspect 171: string << " " 172: else 173: string << " " 174: string << yield( path ) 175: string << " " 176: end 177: return string.squeeze(" ") 178: end