@@ -95,7 +95,7 @@ public class QueryParser extends InputParser {
9595 /** Output declarations. */
9696 private final HashMap <String , Object > sparams = new HashMap <>();
9797 /** QName cache. */
98- private final QNmCache qnames = new QNmCache ();
98+ private final QNmResolver qnames = new QNmResolver ();
9999 /** Local variable. */
100100 private final LocalVars localVars = new LocalVars (this );
101101
@@ -261,7 +261,7 @@ private void finish(final MainModule mm) throws QueryException {
261261 }
262262
263263 // completes the parsing step
264- qnames .assignURI (this , 0 );
264+ qnames .resolve (this , 0 , sc . elemNS );
265265 if (sc .elemNS != null ) sc .ns .add (EMPTY , sc .elemNS , null );
266266 RecordType .resolveRefs (recordTypeRefs , namedRecordTypes );
267267 }
@@ -329,8 +329,10 @@ private void prolog1() throws QueryException {
329329 while (true ) {
330330 final int p = pos ;
331331 if (wsConsumeWs (DECLARE )) {
332- if (wsConsumeWs (DEFAULT )) {
333- if (!defaultNamespaceDecl () && !defaultCollationDecl () && !emptyOrderDecl () &&
332+ if (wsConsumeWs (FIXED )) {
333+ if (!wsConsumeWs (DEFAULT ) || !defaultNamespaceDecl (true )) throw error (DECLINCOMPLETE );
334+ } else if (wsConsumeWs (DEFAULT )) {
335+ if (!defaultNamespaceDecl (false ) && !defaultCollationDecl () && !emptyOrderDecl () &&
334336 !decimalFormatDecl (true )) throw error (DECLINCOMPLETE );
335337 } else if (wsConsumeWs (BOUNDARY_SPACE )) {
336338 boundarySpaceDecl ();
@@ -529,10 +531,11 @@ private void boundarySpaceDecl() throws QueryException {
529531
530532 /**
531533 * Parses the "DefaultNamespaceDecl" rule.
534+ * @param fixed fixed default namespace flag
532535 * @return true if declaration was found
533536 * @throws QueryException query exception
534537 */
535- private boolean defaultNamespaceDecl () throws QueryException {
538+ private boolean defaultNamespaceDecl (final boolean fixed ) throws QueryException {
536539 final boolean elem = wsConsumeWs (ELEMENT );
537540 if (!elem && !wsConsumeWs (FUNCTION )) return false ;
538541 wsCheck (NAMESPACE );
@@ -542,7 +545,9 @@ private boolean defaultNamespaceDecl() throws QueryException {
542545
543546 if (elem ) {
544547 if (!decl .add (ELEMENT )) throw error (DUPLNS );
548+ sc .elemNsFixed = fixed ;
545549 sc .elemNS = uri .length == 0 ? null : uri ;
550+ sc .dirNS = sc .elemNS ;
546551 } else {
547552 if (!decl .add (FUNCTION )) throw error (DUPLNS );
548553 sc .funcNS = uri ;
@@ -682,9 +687,13 @@ private void schemaImport() throws QueryException {
682687 prefix = ncName (NONAME_X , false );
683688 if (eq (prefix , XML , XMLNS )) throw error (BINDXML_X , prefix );
684689 wsCheck ("=" );
685- } else if (wsConsumeWs (DEFAULT )) {
686- wsCheck (ELEMENT );
687- wsCheck (NAMESPACE );
690+ } else {
691+ final boolean fixed = wsConsumeWs (FIXED );
692+ if (fixed || wsConsumeWs (DEFAULT )) {
693+ if (fixed ) wsCheck (DEFAULT );
694+ wsCheck (ELEMENT );
695+ wsCheck (NAMESPACE );
696+ }
688697 }
689698 final byte [] uri = uriLiteral ();
690699 if (prefix != null && uri .length == 0 ) throw error (NSEMPTY );
@@ -2080,7 +2089,7 @@ private void validate() throws QueryException {
20802089
20812090 if (consume (TYPE )) {
20822091 final InputInfo ii = info ();
2083- qnames .add (eQName (SKIPCHECK , QNAME_X ), ii );
2092+ qnames .add (eQName (SKIPCHECK , QNAME_X ), sc , ii );
20842093 }
20852094 consume (STRICT );
20862095 consume (LAX );
@@ -2462,7 +2471,7 @@ private ExprInfo simpleNodeTest(final Kind kind, final boolean all) throws Query
24622471 }
24632472 }
24642473 // name test: prefix:name, name, Q{uri}name
2465- qnames .add (name , kind == Kind . ELEMENT , ii );
2474+ if ( kind == Kind . ELEMENT ) qnames .add (name , sc , ii ); else qnames . add ( name , false , ii );
24662475 return nameTest .apply (name , scope );
24672476 }
24682477 }
@@ -3077,10 +3086,11 @@ private Expr dirElement(final boolean root) throws QueryException {
30773086 // cache namespace information
30783087 final int size = sc .ns .size ();
30793088 final byte [] nse = sc .elemNS ;
3089+ final byte [] nsd = sc .dirNS ;
30803090 final int npos = qnames .size ();
30813091
30823092 final QNm name = new QNm (qnm );
3083- qnames .add (name , ii );
3093+ qnames .add (name , true , ii );
30843094
30853095 final Atts ns = new Atts ();
30863096 final ExprList cont = new ExprList ();
@@ -3170,7 +3180,8 @@ private Expr dirElement(final boolean root) throws QueryException {
31703180 sc .ns .add (prefix , uri );
31713181 } else {
31723182 if (eq (uri , XML_URI )) throw error (XMLNSDEF_X , uri );
3173- sc .elemNS = uri ;
3183+ sc .dirNS = uri ;
3184+ if (!sc .elemNsFixed ) sc .elemNS = sc .dirNS ;
31743185 }
31753186 if (ns .contains (prefix )) throw error (DUPLNSDEF_X , prefix );
31763187 ns .add (prefix , uri );
@@ -3201,7 +3212,7 @@ private Expr dirElement(final boolean root) throws QueryException {
32013212 if (!eq (name .string (), close )) throw error (TAGWRONG_X_X , name .string (), close );
32023213 }
32033214
3204- qnames .assignURI (this , npos );
3215+ qnames .resolve (this , npos , sc . dirNS );
32053216
32063217 // check for duplicate attribute names
32073218 if (atts != null ) {
@@ -3215,6 +3226,7 @@ private Expr dirElement(final boolean root) throws QueryException {
32153226
32163227 sc .ns .size (size );
32173228 sc .elemNS = nse ;
3229+ sc .dirNS = nsd ;
32183230 return new CElem (info (), false , name , ns , cont .finish ());
32193231 }
32203232
@@ -3356,7 +3368,7 @@ private Expr compConstructor() throws QueryException {
33563368 private Expr compElement () throws QueryException {
33573369 final Expr name = compName (NOELEMNAME , true );
33583370 if (name == null ) return null ;
3359- if (name instanceof final QNm qnm ) qnames .add (qnm , info ());
3371+ if (name instanceof final QNm qnm ) qnames .add (qnm , sc , info ());
33603372 skipWs ();
33613373 return current ('{' ) ? new CElem (info (), true , name , new Atts (), enclosedExpr ()) : null ;
33623374 }
0 commit comments