Returns the path nodes that are the result of this step. @param nodes initial path nodes @param stats assess database statistics; if true, return early if step has predicates @return path nodes, or null if nodes cannot be collected
(final ArrayList<PathNode> nodes, final boolean stats)
| 269 | * @return path nodes, or {@code null} if nodes cannot be collected |
| 270 | */ |
| 271 | final ArrayList<PathNode> nodes(final ArrayList<PathNode> nodes, final boolean stats) { |
| 272 | // skip steps with predicates or different namespaces |
| 273 | final Data data = data(); |
| 274 | if(stats && exprs.length != 0 || data == null || data.defaultNs() == null) return null; |
| 275 | |
| 276 | // skip axes other than descendant, child, and attribute |
| 277 | if(!axis.oneOf(ATTRIBUTE, CHILD , SELF, DESCENDANT, DESCENDANT_OR_SELF)) return null; |
| 278 | |
| 279 | // skip processing instructions |
| 280 | final Kind kind = test.kind; |
| 281 | if(kind.oneOf(Kind.GNODE, Kind.PROCESSING_INSTRUCTION)) return null; |
| 282 | |
| 283 | final Names names = kind == Kind.ATTRIBUTE ? data.attrNames : data.elemNames; |
| 284 | final int kn = XNode.dbKind(kind); |
| 285 | final ArrayList<PathNode> tmp = new ArrayList<>(); |
| 286 | final Predicate<Test> addNodes = t -> { |
| 287 | int name = 0; |
| 288 | if(t instanceof final NameTest nt) { |
| 289 | if(nt.name == null) return false; |
| 290 | name = names.index(nt.name); |
| 291 | } |
| 292 | for(final PathNode pn : nodes) { |
| 293 | if(axis.oneOf(SELF, DESCENDANT_OR_SELF)) { |
| 294 | if(kn == -1 || kn == pn.kind && (name == 0 || name == pn.name)) { |
| 295 | if(!tmp.contains(pn)) tmp.add(pn); |
| 296 | } |
| 297 | } |
| 298 | if(axis != SELF) add(pn, tmp, name, kn); |
| 299 | } |
| 300 | return true; |
| 301 | }; |
| 302 | |
| 303 | // add nodes |
| 304 | if(test instanceof final UnionTest ut) { |
| 305 | for(final Test t : ut.tests) { |
| 306 | if(!addNodes.test(t)) return null; |
| 307 | } |
| 308 | } else if(!addNodes.test(test)) { |
| 309 | return null; |
| 310 | } |
| 311 | return tmp; |
| 312 | } |
| 313 | |
| 314 | /** |
| 315 | * Adds path nodes to the list if they comply with the given test conditions. |