|
1 | 1 | # frozen_string_literal: false
|
| 2 | + |
2 | 3 | require_relative '../namespace'
|
3 | 4 | require_relative '../xmltokens'
|
4 | 5 |
|
@@ -44,60 +45,87 @@ def abbreviate(path_or_parsed)
|
44 | 45 | else
|
45 | 46 | parsed = path_or_parsed
|
46 | 47 | end
|
47 |
| - path = "" |
48 |
| - document = false |
| 48 | + components = [] |
| 49 | + component = nil |
| 50 | + previous_op = nil |
49 | 51 | while parsed.size > 0
|
50 | 52 | op = parsed.shift
|
51 | 53 | case op
|
52 | 54 | when :node
|
| 55 | + component << "node()" |
53 | 56 | when :attribute
|
54 |
| - path << "/" if path.size > 0 |
55 |
| - path << "@" |
| 57 | + component = "@" |
| 58 | + components << component |
56 | 59 | when :child
|
57 |
| - path << "/" if path.size > 0 |
| 60 | + component = "" |
| 61 | + components << component |
58 | 62 | when :descendant_or_self
|
59 |
| - path << "//" |
| 63 | + next_op = parsed[0] |
| 64 | + if next_op == :node |
| 65 | + parsed.shift |
| 66 | + component = "" |
| 67 | + components << component |
| 68 | + else |
| 69 | + component = "descendant-or-self::" |
| 70 | + components << component |
| 71 | + end |
60 | 72 | when :self
|
61 |
| - path << "/" |
| 73 | + next_op = parsed[0] |
| 74 | + if next_op == :node |
| 75 | + parsed.shift |
| 76 | + components << "." |
| 77 | + else |
| 78 | + component = "self::" |
| 79 | + components << component |
| 80 | + end |
62 | 81 | when :parent
|
63 |
| - path << "/.." |
| 82 | + next_op = parsed[0] |
| 83 | + if next_op == :node |
| 84 | + parsed.shift |
| 85 | + components << ".." |
| 86 | + else |
| 87 | + component = "parent::" |
| 88 | + components << component |
| 89 | + end |
64 | 90 | when :any
|
65 |
| - path << "*" |
| 91 | + component << "*" |
66 | 92 | when :text
|
67 |
| - path << "text()" |
| 93 | + component << "text()" |
68 | 94 | when :following, :following_sibling,
|
69 | 95 | :ancestor, :ancestor_or_self, :descendant,
|
70 | 96 | :namespace, :preceding, :preceding_sibling
|
71 |
| - path << "/" unless path.size == 0 |
72 |
| - path << op.to_s.tr("_", "-") |
73 |
| - path << "::" |
| 97 | + component = op.to_s.tr("_", "-") << "::" |
| 98 | + components << component |
74 | 99 | when :qname
|
75 | 100 | prefix = parsed.shift
|
76 | 101 | name = parsed.shift
|
77 |
| - path << prefix+":" if prefix.size > 0 |
78 |
| - path << name |
| 102 | + component << prefix+":" if prefix.size > 0 |
| 103 | + component << name |
79 | 104 | when :predicate
|
80 |
| - path << '[' |
81 |
| - path << predicate_to_path( parsed.shift ) {|x| abbreviate( x ) } |
82 |
| - path << ']' |
| 105 | + component << '[' |
| 106 | + component << predicate_to_path(parsed.shift) {|x| abbreviate(x)} |
| 107 | + component << ']' |
83 | 108 | when :document
|
84 |
| - document = true |
| 109 | + components << "" |
85 | 110 | when :function
|
86 |
| - path << parsed.shift |
87 |
| - path << "( " |
88 |
| - path << predicate_to_path( parsed.shift[0] ) {|x| abbreviate( x )} |
89 |
| - path << " )" |
| 111 | + component << parsed.shift |
| 112 | + component << "( " |
| 113 | + component << predicate_to_path(parsed.shift[0]) {|x| abbreviate(x)} |
| 114 | + component << " )" |
90 | 115 | when :literal
|
91 |
| - path << %Q{ "#{parsed.shift}" } |
| 116 | + component << quote_literal(parsed.shift) |
92 | 117 | else
|
93 |
| - path << "/" unless path.size == 0 |
94 |
| - path << "UNKNOWN(" |
95 |
| - path << op.inspect |
96 |
| - path << ")" |
| 118 | + component << "UNKNOWN(" |
| 119 | + component << op.inspect |
| 120 | + component << ")" |
97 | 121 | end
|
| 122 | + previous_op = op |
| 123 | + end |
| 124 | + if components == [""] |
| 125 | + "/" |
| 126 | + else |
| 127 | + components.join("/") |
98 | 128 | end
|
99 |
| - path = "/"+path if document |
100 |
| - path |
101 | 129 | end
|
102 | 130 |
|
103 | 131 | def expand(path_or_parsed)
|
@@ -133,7 +161,6 @@ def expand(path_or_parsed)
|
133 | 161 | when :document
|
134 | 162 | document = true
|
135 | 163 | else
|
136 |
| - path << "/" unless path.size == 0 |
137 | 164 | path << "UNKNOWN("
|
138 | 165 | path << op.inspect
|
139 | 166 | path << ")"
|
@@ -166,32 +193,26 @@ def predicate_to_path(parsed, &block)
|
166 | 193 | end
|
167 | 194 | left = predicate_to_path( parsed.shift, &block )
|
168 | 195 | right = predicate_to_path( parsed.shift, &block )
|
169 |
| - path << " " |
170 | 196 | path << left
|
171 | 197 | path << " "
|
172 | 198 | path << op.to_s
|
173 | 199 | path << " "
|
174 | 200 | path << right
|
175 |
| - path << " " |
176 | 201 | when :function
|
177 | 202 | parsed.shift
|
178 | 203 | name = parsed.shift
|
179 | 204 | path << name
|
180 |
| - path << "( " |
| 205 | + path << "(" |
181 | 206 | parsed.shift.each_with_index do |argument, i|
|
182 | 207 | path << ", " if i > 0
|
183 | 208 | path << predicate_to_path(argument, &block)
|
184 | 209 | end
|
185 |
| - path << " )" |
| 210 | + path << ")" |
186 | 211 | when :literal
|
187 | 212 | parsed.shift
|
188 |
| - path << " " |
189 | 213 | path << quote_literal(parsed.shift)
|
190 |
| - path << " " |
191 | 214 | else
|
192 |
| - path << " " |
193 | 215 | path << yield( parsed )
|
194 |
| - path << " " |
195 | 216 | end
|
196 | 217 | return path.squeeze(" ")
|
197 | 218 | end
|
|
0 commit comments