4646package org .exist .indexing .range ;
4747
4848import org .exist .dom .QName ;
49+ import org .exist .dom .persistent .ElementImpl ;
50+ import org .exist .dom .persistent .NodeImpl ;
4951import org .exist .storage .ElementValue ;
5052import org .exist .storage .NodePath ;
5153import org .exist .util .DatabaseConfigurationException ;
7880 */
7981public class RangeIndexConfigAttributeCondition extends RangeIndexConfigCondition {
8082
81- private final String attributeName ;
82- private final QName attribute ;
83+ private final QName attributeName ;
8384 private @ Nullable final String value ;
8485 private final Operator operator ;
8586 private final boolean caseSensitive ;
@@ -96,13 +97,23 @@ public RangeIndexConfigAttributeCondition(final Element elem, final NodePath par
9697 "Range index module: Attribute condition cannot be defined for an attribute:" + parentPath );
9798 }
9899
99- this . attributeName = elem .getAttribute ("attribute" );
100- if (this . attributeName .isEmpty ()) {
100+ final String attributeValue = elem .getAttribute ("attribute" );
101+ if (attributeValue .isEmpty ()) {
101102 throw new DatabaseConfigurationException ("Range index module: Empty or no attribute qname in condition" );
102103 }
103104
104105 try {
105- this .attribute = new QName (QName .extractLocalName (this .attributeName ), XMLConstants .NULL_NS_URI , QName .extractPrefix (this .attributeName ), ElementValue .ATTRIBUTE );
106+ final String attrLocalName = QName .extractLocalName (attributeValue );
107+ @ Nullable final String attrPrefix = QName .extractPrefix (attributeValue );
108+ if (attrPrefix != null ) {
109+ @ Nullable final String attrNamespace = findNamespaceForPrefix (attrPrefix , (ElementImpl ) elem );
110+ if (attrNamespace == null ) {
111+ throw new DatabaseConfigurationException ("Range index module: Missing namespace declaration for attribute qname in condition" );
112+ }
113+ this .attributeName = new QName (attrLocalName , attrNamespace , attrPrefix , ElementValue .ATTRIBUTE );
114+ } else {
115+ this .attributeName = new QName (attrLocalName , XMLConstants .NULL_NS_URI , null , ElementValue .ATTRIBUTE );
116+ }
106117 } catch (final QName .IllegalQNameException e ) {
107118 throw new DatabaseConfigurationException ("Rand index module error: " + e .getMessage (), e );
108119 }
@@ -171,6 +182,24 @@ public RangeIndexConfigAttributeCondition(final Element elem, final NodePath par
171182
172183 }
173184
185+ private static @ Nullable String findNamespaceForPrefix (final String prefix , ElementImpl contextElem ) {
186+ while (contextElem != null ) {
187+ final String namespace = contextElem .getNamespaceForPrefix (prefix );
188+ if (namespace != null ) {
189+ return namespace ;
190+ }
191+
192+ @ Nullable final Node parentNode = contextElem .getParentNode ();
193+ if (parentNode != null && parentNode instanceof ElementImpl ) {
194+ contextElem = (ElementImpl ) parentNode ;
195+ } else {
196+ contextElem = null ;
197+ }
198+ }
199+
200+ return null ;
201+ }
202+
174203 // lazily evaluate lowercase value to convert once when needed
175204 private String getLowercaseValue () {
176205 if (this .lowercaseValue == null ) {
@@ -184,8 +213,16 @@ private String getLowercaseValue() {
184213
185214 @ Override
186215 public boolean matches (final Node node ) {
216+ final String attrValue ;
217+ if (attributeName .hasNamespace ()) {
218+ attrValue = ((Element ) node ).getAttributeNS (attributeName .getNamespaceURI (), attributeName .getLocalPart ());
219+ } else {
220+ attrValue = ((Element ) node ).getAttribute (attributeName .getLocalPart ());
221+ }
222+
187223 return node .getNodeType () == Node .ELEMENT_NODE
188- && matchValue (((Element ) node ).getAttribute (attributeName ));
224+ && matchValue (attrValue );
225+
189226 }
190227
191228 private boolean matchValue (final String testValue ) {
@@ -312,7 +349,7 @@ public boolean find(final Predicate predicate) {
312349 }
313350
314351 final QName qname = testStep .getTest ().getName ();
315- if (qname .getNameType () != ElementValue .ATTRIBUTE || !qname .equals (attribute )) {
352+ if (qname .getNameType () != ElementValue .ATTRIBUTE || !qname .equals (attributeName )) {
316353 return false ;
317354 }
318355
0 commit comments