/** * Compares two nodes for their unique order. * * @param node1 first node * @param node2 node to be compared * @return {@code 0} if the nodes are identical, or {@code 1}/{@code -1} if the first node appears * after/before the second */ static int diff(final ANode node1, final ANode node2) { // cache parents of first node final ANodeList nl = new ANodeList(); for (ANode n = node1; n != null; n = n.parent()) { if (n == node2) return 1; nl.add(n); } // find lowest common ancestor ANode c2 = node2; LOOP: for (ANode n = node2; (n = n.parent()) != null; ) { final int is = nl.size(); for (int i = 1; i < is; i++) { if (n == node1) return -1; if (!nl.get(i).is(n)) continue; // check which node appears as first LCA child final ANode c1 = nl.get(i - 1); final BasicNodeIter ir = n.children(); for (ANode c; (c = ir.next()) != null; ) { if (c.is(c1)) return -1; if (c.is(c2)) return 1; } break LOOP; } c2 = n; } // subtraction is used instead of comparison to support overflow of node id return node1.id - node2.id < 0 ? -1 : 1; }
@Override public Str item(final QueryContext qc, final InputInfo ii) throws QueryException { ANode node, par = toNode(exprs[0], qc); do { node = par; par = node.parent(); } while (par != null); final DBNode dbn = toDBNode(node); return dbn.kind() == Data.DOC ? Str.get(dbn.data().text(dbn.pre(), true)) : Str.ZERO; }
/** * Returns a copy of the namespace hierarchy. * * @param sc static context (can be {@code null}) * @return namespaces */ public final Atts nsScope(final StaticContext sc) { final Atts ns = new Atts(); ANode node = this; do { final Atts nsp = node.namespaces(); if (nsp != null) { for (int a = nsp.size() - 1; a >= 0; a--) { final byte[] key = nsp.name(a); if (!ns.contains(key)) ns.add(key, nsp.value(a)); } } node = node.parent(); } while (node != null && node.type == NodeType.ELM); if (sc != null) sc.ns.inScope(ns); return ns; }