/** * Adds the specified namespace to the namespace array. If the prefix is already used for another * URI, a new name is generated. * * @param pref prefix * @param uri uri * @param ns namespaces * @return resulting prefix */ private static byte[] addNS(final byte[] pref, final byte[] uri, final Atts ns) { final byte[] u = ns.string(pref); if (u == null) { // add undeclared namespace ns.add(pref, uri); } else if (!eq(u, uri)) { // prefixes with different URIs exist; new one must be replaced byte[] apref = null; // check if one of the existing prefixes can be adopted for (int c = 0; c < ns.size(); c++) { if (eq(ns.string(c), uri)) apref = ns.name(c); } // if negative, generate a new one that is not used yet if (apref == null) { int i = 1; do { apref = concat(pref, new byte[] {'_'}, token(i++)); } while (ns.contains(apref)); ns.add(apref, uri); } return apref; } return null; }
public ANode call(Str str) throws IOException { String input = str.toJava(); SingleParser singleParser = new SingleParser(new IOContent(""), MainOptions.get()) { @Override protected void parse() throws IOException {} }; MemBuilder memBuilder = new MemBuilder(input, singleParser); memBuilder.init(); BaseXTreeBuilder treeBuilder = new BaseXTreeBuilder(memBuilder); Parse_XQDocComments parser = new Parse_XQDocComments(); parser.initialize(input, treeBuilder); try { execute(parser); } catch (ParseException pe) { memBuilder = new MemBuilder(input, singleParser); memBuilder.init(); Atts atts = new Atts(); atts.add(Token.token("b"), Token.token(pe.getBegin() + 1)); atts.add(Token.token("e"), Token.token(pe.getEnd() + 1)); if (pe.getOffending() < 0) { atts.add(Token.token("s"), Token.token(pe.getState())); } else { atts.add(Token.token("o"), Token.token(pe.getOffending())); atts.add(Token.token("x"), Token.token(pe.getExpected())); } memBuilder.openElem(Token.token("ERROR"), atts, new Atts()); memBuilder.text(Token.token(parser.getErrorMessage(pe))); memBuilder.closeElem(); } return new DBNode(memBuilder.data()); }
/** * Inherits namespaces. * * @param node to be modified * @param nsp in-scope namespaces */ private static void inherit(final ANode node, final Atts nsp) { final Atts ns = node.namespaces(); for (int a = nsp.size() - 1; a >= 0; a--) { final byte[] pref = nsp.name(a); if (!ns.contains(pref)) ns.add(pref, nsp.string(a)); } }
/** * Returns all namespace keys and values. Should be only called for element nodes. * * @param pre pre value * @return key and value ids */ public final Atts ns(final int pre) { final Atts as = new Atts(); if (nsFlag(pre)) { final int[] nsp = nspaces.get(pre, this); for (int n = 0; n < nsp.length; n += 2) as.add(nspaces.prefix(nsp[n]), nspaces.uri(nsp[n + 1])); } return as; }
/** * 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; }
/** * Returns the namespace hierarchy. * * @param nsInherit copy-namespaces inherit * @return namespaces [LW][LK] Namespaces: this isn't enough */ public final Atts nsScope(final boolean nsInherit) { final Atts ns = new Atts(); ANode n = this; do { final Atts nns = n.ns(); if (!nsInherit) return nns; if (nns != null) { for (int a = nns.size - 1; a >= 0; a--) { final byte[] key = nns.key[a]; if (!ns.contains(key)) ns.add(key, nns.val[a]); } } n = n.parent(); } while (n != null && n.type == NodeType.ELM); return ns; }
@Override protected void attribute(final byte[] name, final byte[] value, final boolean standalone) { byte[] prefix = null; if (startsWith(name, XMLNS)) { if (name.length == 5) { prefix = EMPTY; } else if (name[5] == ':') { prefix = substring(name, 6); } } if (prefix != null) { namespaces.put(prefix, value); } else { attributes.add(name, value); } }
@Override public FElem item(final QueryContext ctx, final InputInfo ii) throws QueryException { final int s = prepare(ctx); try { // adds in-scope namespaces final Atts ns = new Atts(); for (int i = 0; i < nspaces.size(); ++i) { ns.add(nspaces.name(i), nspaces.string(i)); } // create and check QName final QNm nm = qname(ctx, ii); final byte[] cp = nm.prefix(), cu = nm.uri(); if (eq(cp, XML) ^ eq(cu, XMLURI)) CEXML.thrw(input, cu, cp); if (eq(cu, XMLNSURI)) CEINV.thrw(input, cu); if (eq(cp, XMLNS)) CEINV.thrw(input, cp); // analyze element namespace unless it is "xml" if (!eq(cp, XML)) { // request namespace for the specified uri final byte[] uri = ctx.sc.ns.uri(cp); // check if element has a namespace if (nm.hasURI()) { // add to statically known namespaces if (!comp && (uri == null || !eq(uri, cu))) ctx.sc.ns.add(cp, cu); // add to in-scope namespaces if (!ns.contains(cp)) ns.add(cp, cu); } else { // element has no namespace: assign default uri nm.uri(uri); } } // create child and attribute nodes final Constr constr = new Constr(ii, ctx).add(expr); if (constr.errAtt) NOATTALL.thrw(input); if (constr.errNS) NONSALL.thrw(input); if (constr.duplAtt != null) (comp ? CATTDUPL : ATTDUPL).thrw(input, constr.duplAtt); if (constr.duplNS != null) DUPLNSCONS.thrw(input, constr.duplNS); // create node final FElem node = new FElem(nm, constr.children, constr.atts, ns); // add namespaces from constructor final Atts cns = constr.nspaces; for (int a = 0; a < cns.size(); ++a) { addNS(cns.name(a), cns.string(a), ns); } // update parent references of attributes and add namespaces for (int a = 0; a < constr.atts.size(); ++a) { constr.atts.get(a).parent(node); final ANode att = constr.atts.get(a); final QNm qnm = att.qname(); // skip attributes without prefixes or URIs if (!qnm.hasPrefix() || !qnm.hasURI()) continue; // skip XML namespace final byte[] apref = qnm.prefix(); if (eq(apref, XML)) continue; final byte[] auri = qnm.uri(); final byte[] npref = addNS(apref, auri, ns); if (npref != null) { constr.atts.item[a] = new FAttr(new QNm(concat(npref, COLON, qnm.local()), auri), att.string()); } } // add inherited namespaces final Atts stack = ctx.sc.ns.stack(); for (int a = stack.size() - 1; a >= 0; a--) { final byte[] pref = stack.name(a); if (!ns.contains(pref)) ns.add(pref, stack.string(a)); } // update parent references of children for (int c = 0; c < constr.children.size(); ++c) { final ANode child = constr.children.get(c).parent(node); // add inherited and remove unused namespaces if (child.type == NodeType.ELM) { if (ctx.sc.nsInherit) inherit(child, ns); if (!ctx.sc.nsPreserve) noPreserve(child); child.optimize(); } } // return generated and optimized node return node.optimize(); } finally { ctx.sc.ns.size(s); } }
/** * Stores a new prefix and namespace. * * @param prefix prefix * @param uri namespace uri */ private void put(final byte[] prefix, final byte[] uri) { if (decls == null) decls = new Atts(); decls.add(prefix, uri); }
static { // reserved namespaces NS.add(XML, XMLURI); NS.add(XS, XSURI); NS.add(XSI, XSIURI); NS.add(FN, FNURI); NS.add(MATH, MATHURI); NS.add(MAP, MAPURI); NS.add(ANN, ANNURI); RESERVED = NS.size(); // implementation-defined pre-declarations NS.add(LOCAL, LOCALURI); NS.add(OUTPUT, OUTPUTURI); NS.add(ERR, ERRORURI); // EXPath namespaces NS.add(EXPERR, EXPERROR); NS.add(CRYPTO, CRYPTOURI); NS.add(FILE, FILEURI); NS.add(HTTP, HTTPURI); NS.add(PKG, PKGURI); NS.add(ZIP, ZIPURI); // EXQuery namespaces NS.add(RESTXQ, RESTXQURI); // BaseX namespaces NS.add(BXERR, BXERRORS); NS.add(BASEX, BASEXURI); NS.add(ADMIN, ADMINURI); NS.add(ARCHIVE, ARCHIVEURI); NS.add(CLIENT, CLIENTURI); NS.add(CONVERT, CONVERTURI); NS.add(DB, DBURI); NS.add(FETCH, FETCHURI); NS.add(FT, FTURI); NS.add(HASH, HASHURI); NS.add(HOF, HOFURI); NS.add(HTML, HTMLURI); NS.add(INDEX, INDEXURI); NS.add(JSON, JSONURI); NS.add(OUT, OUTURI); NS.add(PROC, PROCURI); NS.add(PROF, PROFURI); NS.add(QUERY, QUERYURI); NS.add(RANDOM, RANDOMURI); NS.add(REPO, REPOURI); NS.add(SQL, SQLURI); NS.add(STREAM, STREAMURI); NS.add(VLDT, VALIDATEURI); NS.add(XSLT, XSLTURI); NS.add(XQRY, XQUERYURI); NS.add(XQUNIT, XQUNITURI); }