/** * Adds path nodes to the list if they comply with the given test conditions. * * @param node root node * @param nodes output nodes * @param name name id, or {@code 0} as wildcard * @param kind node kind, or {@code -1} for all types */ private void add( final PathNode node, final ObjList<PathNode> nodes, final int name, final int kind) { for (final PathNode n : node.ch) { if (axis == Axis.DESC || axis == Axis.DESCORSELF) { add(n, nodes, name, kind); } if (kind == -1 && n.kind != Data.ATTR ^ axis == Axis.ATTR || kind == n.kind && (name == 0 || name == n.name)) { if (!nodes.contains(n)) nodes.add(n); } } }
/** * Returns the path nodes that are the result of this step. * * @param nodes initial path nodes * @param data data reference * @return resulting path nodes, or {@code null} if nodes cannot be evaluated */ final ObjList<PathNode> nodes(final ObjList<PathNode> nodes, final Data data) { // skip steps with predicates or different namespaces if (preds.length != 0 || data.nspaces.globalNS() == null) return null; // check restrictions on node type int kind = -1, name = 0; if (test.type != null) { kind = ANode.kind(test.type); if (kind == Data.PI) return null; if (test.test == Name.NAME) { // element/attribute test (*:ln) final Names names = kind == Data.ATTR ? data.atnindex : data.tagindex; name = names.id(((NameTest) test).ln); } else if (test.test != null && test.test != Name.ALL) { // skip namespace and standard tests return null; } } // skip axes other than descendant, child, and attribute if (axis != Axis.ATTR && axis != Axis.CHILD && axis != Axis.DESC && axis != Axis.DESCORSELF && axis != Axis.SELF) return null; final ObjList<PathNode> tmp = new ObjList<PathNode>(); for (final PathNode n : nodes) { if (axis == Axis.SELF || axis == Axis.DESCORSELF) { if (kind == -1 || kind == n.kind && (name == 0 || name == n.name)) { if (!tmp.contains(n)) tmp.add(n); } } if (axis != Axis.SELF) add(n, tmp, name, kind); } return tmp; }