@Override public NodeIter iter(final QueryContext ctx) throws QueryException { final Value v = checkCtx(ctx); if (!v.type.isNode()) NODESPATH.thrw(input, AxisStep.this, v.type); final AxisIter ai = axis.iter((ANode) v); final NodeCache nc = new NodeCache(); for (ANode n; (n = ai.next()) != null; ) if (test.eval(n)) nc.add(n.finish()); // evaluate predicates for (final Expr p : preds) { ctx.size = nc.size(); ctx.pos = 1; int c = 0; for (int n = 0; n < nc.size(); ++n) { ctx.value = nc.get(n); final Item i = p.test(ctx, input); if (i != null) { // assign score value nc.get(n).score(i.score()); nc.item[c++] = nc.get(n); } ctx.pos++; } nc.size(c); } return nc; }
/** * Extracts connection options. * * @param arg argument with options * @param root expected root element * @param ctx query context * @return options * @throws QueryException query exception */ private TokenObjMap<Object> options(final int arg, final QNm root, final QueryContext ctx) throws QueryException { // initialize token map final TokenObjMap<Object> tm = new TokenObjMap<Object>(); // argument does not exist... if (arg >= expr.length) return tm; // empty sequence... final Item it = expr[arg].item(ctx, input); if (it == null) return tm; // XQuery map: convert to internal map if (it instanceof Map) return ((Map) it).tokenJavaMap(input); // no element: convert XQuery map to internal map if (!it.type().eq(SeqType.ELM)) throw NODFUNTYPE.thrw(input, this, it.type); // parse nodes ANode node = (ANode) it; if (!node.qname().eq(root)) PARWHICH.thrw(input, node.qname()); // interpret query parameters final AxisIter ai = node.children(); while ((node = ai.next()) != null) { final QNm qn = node.qname(); if (!qn.uri().eq(Uri.uri(SQLURI))) PARWHICH.thrw(input, qn); tm.add(qn.ln(), node.children().next()); } return tm; }
/** * Returns the value of the specified attribute, or {@code null}. * * @param name attribute to be found * @return attribute value */ public byte[] attribute(final QNm name) { final AxisIter ai = attributes(); while (true) { final ANode node = ai.next(); if (node == null) return null; if (node.qname().eq(name)) return node.atom(); } }
/** * Removes unused namespaces. * * @param node to be modified */ private static void noPreserve(final ANode node) { final Atts ns = node.namespaces(); final byte[] pref = node.qname().prefix(); for (int i = ns.size() - 1; i >= 0; i--) { boolean f = eq(ns.name(i), pref); final AxisIter atts = node.attributes(); for (ANode it; f && (it = atts.next()) != null; ) { f |= eq(it.qname().prefix(), pref); } if (!f) ns.delete(i); } }
/** * Sets the parameters of a prepared statement. * * @param params parameters * @param stmt prepared statement * @throws QueryException query exception */ private void setParameters(final AxisMoreIter params, final PreparedStatement stmt) throws QueryException { int i = 0; for (ANode next; (next = params.next()) != null; ) { // Check name if (!next.qname().eq(E_PARAM)) PARWHICH.thrw(input, next.qname()); final AxisIter attrs = next.attributes(); byte[] paramType = null; boolean isNull = false; for (ANode attr; (attr = attrs.next()) != null; ) { // Attribute "type" if (eq(attr.nname(), TYPE)) paramType = attr.atom(); // Attribute "null" else if (eq(attr.nname(), NULL)) isNull = attr.atom() != null && Bln.parse(attr.atom(), input); // Not expected attribute else throw NOTEXPATTR.thrw(input, string(attr.nname())); } if (paramType == null) NOPARAMTYPE.thrw(input); final byte[] v = next.atom(); isNull |= v.length == 0; setParam(++i, stmt, paramType, isNull ? null : string(v), isNull); } }
/** * Counts the numbers of <sql:parameter/> elements. * * @param params element <sql:parameter/> * @return number of parameters */ private long countParams(final ANode params) { final AxisIter ch = params.children(); long c = ch.size(); if (c == -1) do ++c; while (ch.next() != null); return c; }