class REXML::Parsers::XPathParser

def abbreviate(path_or_parsed)

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