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
|