Class REXML::Parsers::XPathParser
In: rexml/parsers/xpathparser.rb
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!

Methods

Included Modules

XMLTokens

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 match
NodeTest
  | ('*' | 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

[Source]

# File rexml/parsers/xpathparser.rb, line 33
      def abbreviate( path )
        path = path.kind_of?(String) ? parse( path ) : path
        string = ""
        document = false
        while path.size > 0
          op = path.shift
          case op
          when :node
          when :attribute
                                                string << "/" if string.size > 0
                                                string << "@"
          when :child
                                                string << "/" if string.size > 0
          when :descendant_or_self
            string << "/"
          when :self
            string << "."
          when :parent
            string << ".."
          when :any
            string << "*"
                                        when :text
                                                string << "text()"
          when :following, :following_sibling, 
                :ancestor, :ancestor_or_self, :descendant, 
                :namespace, :preceding, :preceding_sibling
            string << "/" unless string.size == 0
            string << op.to_s.tr("_", "-")
            string << "::"
          when :qname
            prefix = path.shift
            name = path.shift
            string << prefix+":" if prefix.size > 0
            string << name
          when :predicate
            string << '['
            string << predicate_to_string( path.shift ) {|x| abbreviate( x ) }
            string << ']'
          when :document
            document = true
                                        when :function
                                                string << path.shift
                                                string << "( "
                                                string << predicate_to_string( path.shift[0] ) {|x| abbreviate( x )}
                                                string << " )"
                                        when :literal
                                                string << %Q{ "#{path.shift}" }
          else
            string << "/" unless string.size == 0
            string << "UNKNOWN("
            string << op.inspect
            string << ")"
          end
        end
                                string = "/"+string if document
        return string
      end

[Source]

# File rexml/parsers/xpathparser.rb, line 91
      def expand( path )
        path = path.kind_of?(String) ? parse( path ) : path
        string = ""
        document = false
        while path.size > 0
          op = path.shift
          case op
          when :node
            string << "node()"
          when :attribute, :child, :following, :following_sibling, 
                :ancestor, :ancestor_or_self, :descendant, :descendant_or_self,
                :namespace, :preceding, :preceding_sibling, :self, :parent
            string << "/" unless string.size == 0
            string << op.to_s.tr("_", "-")
            string << "::"
          when :any
            string << "*"
          when :qname
            prefix = path.shift
            name = path.shift
            string << prefix+":" if prefix.size > 0
            string << name
          when :predicate
            string << '['
            string << predicate_to_string( path.shift ) { |x| expand(x) }
            string << ']'
          when :document
            document = true
          else
            string << "/" unless string.size == 0
            string << "UNKNOWN("
            string << op.inspect
            string << ")"
          end
        end
        string = "/"+string if document
        return string
      end

[Source]

# File rexml/parsers/xpathparser.rb, line 14
      def namespaces=( namespaces )
        Functions::namespace_context = namespaces
        @namespaces = namespaces
      end

[Source]

# File rexml/parsers/xpathparser.rb, line 19
      def parse path
        path.gsub!(/([\(\[])\s+/, '\1') # Strip ignorable spaces
        path.gsub!( /\s+([\]\)])/, '\1' )
        parsed = []
        path = OrExpr(path, parsed)
        parsed
      end

[Source]

# File rexml/parsers/xpathparser.rb, line 27
      def predicate path
        parsed = []
        Predicate( "[#{path}]", parsed )
        parsed
      end

[Source]

# File rexml/parsers/xpathparser.rb, line 130
      def predicate_to_string( path, &block )
        string = ""
        case path[0]
        when :and, :or, :mult, :plus, :minus, :neq, :eq, :lt, :gt, :lteq, :gteq, :div, :mod, :union
          op = path.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_string( path.shift, &block )
          right = predicate_to_string( path.shift, &block )
          string << " "
          string << left
          string << " "
          string << op.to_s
          string << " "
          string << right
          string << " "
        when :function
          path.shift
          name = path.shift
          string << name
          string << "( "
          string << predicate_to_string( path.shift, &block )
          string << " )"
        when :literal
          path.shift
          string << " "
          string << path.shift.inspect
          string << " "
        else
          string << " "
          string << yield( path )
          string << " "
        end
        return string.squeeze(" ")
      end

[Validate]