Parses the "PathExpr" rule. @return query expression or null @throws QueryException query exception
()
| 2193 | * @throws QueryException query exception |
| 2194 | */ |
| 2195 | private Expr path() throws QueryException { |
| 2196 | checkInit(); |
| 2197 | |
| 2198 | final ExprList el; |
| 2199 | Expr root = null; |
| 2200 | if(consume('/')) { |
| 2201 | final InputInfo ii = info(); |
| 2202 | root = Function._UTIL_ROOT.get(ii, new ContextValue(ii)); |
| 2203 | el = new ExprList(); |
| 2204 | final Expr expr; |
| 2205 | if(consume('/')) { |
| 2206 | // two slashes: absolute descendant path |
| 2207 | checkAxis(Axis.DESCENDANT); |
| 2208 | add(el, new CachedStep(info(), Axis.DESCENDANT_OR_SELF, NodeTest.GNODE)); |
| 2209 | mark(); |
| 2210 | expr = step(true); |
| 2211 | } else { |
| 2212 | // one slash: absolute child path |
| 2213 | checkAxis(Axis.CHILD); |
| 2214 | mark(); |
| 2215 | expr = step(false); |
| 2216 | // no more steps: return root expression |
| 2217 | if(expr == null) return root; |
| 2218 | } |
| 2219 | add(el, expr); |
| 2220 | } else { |
| 2221 | // relative path (no preceding slash) |
| 2222 | mark(); |
| 2223 | final Expr expr = step(false); |
| 2224 | if(expr == null) return null; |
| 2225 | // return expression if no slash follows |
| 2226 | if(current() != '/' && !(expr instanceof Step)) return expr; |
| 2227 | el = new ExprList(); |
| 2228 | if(expr instanceof Step) add(el, expr); |
| 2229 | else root = expr; |
| 2230 | } |
| 2231 | relativePath(el); |
| 2232 | return Path.get(info(), root, el.finish()); |
| 2233 | } |
| 2234 | |
| 2235 | /** |
| 2236 | * Parses the "RelativePathExpr" rule. |
no test coverage detected