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 ;
7779 */
7880public class RangeIndexConfigAttributeCondition extends RangeIndexConfigCondition {
7981
80- private final String attributeName ;
81- private final QName attribute ;
82+ private final QName attributeName ;
8283 private @ Nullable final String value ;
8384 private final Operator operator ;
8485 private final boolean caseSensitive ;
@@ -94,13 +95,23 @@ public RangeIndexConfigAttributeCondition(Element elem, NodePath parentPath) thr
9495 throw new DatabaseConfigurationException ("Range index module: Attribute condition cannot be defined for an attribute:" + parentPath .toString ());
9596 }
9697
97- this . attributeName = elem .getAttribute ("attribute" );
98- if (this . attributeName .isEmpty ()) {
98+ final String attributeValue = elem .getAttribute ("attribute" );
99+ if (attributeValue .isEmpty ()) {
99100 throw new DatabaseConfigurationException ("Range index module: Empty or no attribute qname in condition" );
100101 }
101102
102103 try {
103- this .attribute = new QName (QName .extractLocalName (this .attributeName ), XMLConstants .NULL_NS_URI , QName .extractPrefix (this .attributeName ), ElementValue .ATTRIBUTE );
104+ final String attrLocalName = QName .extractLocalName (attributeValue );
105+ @ Nullable final String attrPrefix = QName .extractPrefix (attributeValue );
106+ if (attrPrefix != null ) {
107+ @ Nullable final String attrNamespace = findNamespaceForPrefix (attrPrefix , (ElementImpl ) elem );
108+ if (attrNamespace == null ) {
109+ throw new DatabaseConfigurationException ("Range index module: Missing namespace declaration for attribute qname in condition" );
110+ }
111+ this .attributeName = new QName (attrLocalName , attrNamespace , attrPrefix , ElementValue .ATTRIBUTE );
112+ } else {
113+ this .attributeName = new QName (attrLocalName , XMLConstants .NULL_NS_URI , null , ElementValue .ATTRIBUTE );
114+ }
104115 } catch (final QName .IllegalQNameException e ) {
105116 throw new DatabaseConfigurationException ("Rand index module error: " + e .getMessage (), e );
106117 }
@@ -169,6 +180,24 @@ public RangeIndexConfigAttributeCondition(Element elem, NodePath parentPath) thr
169180
170181 }
171182
183+ private static @ Nullable String findNamespaceForPrefix (final String prefix , ElementImpl contextElem ) {
184+ while (contextElem != null ) {
185+ final String namespace = contextElem .getNamespaceForPrefix (prefix );
186+ if (namespace != null ) {
187+ return namespace ;
188+ }
189+
190+ @ Nullable final Node parentNode = contextElem .getParentNode ();
191+ if (parentNode != null && parentNode instanceof ElementImpl ) {
192+ contextElem = (ElementImpl ) parentNode ;
193+ } else {
194+ contextElem = null ;
195+ }
196+ }
197+
198+ return null ;
199+ }
200+
172201 // lazily evaluate lowercase value to convert once when needed
173202 private String getLowercaseValue () {
174203 if (this .lowercaseValue == null ) {
@@ -180,15 +209,18 @@ private String getLowercaseValue() {
180209 return this .lowercaseValue ;
181210 }
182211
183-
184212 @ Override
185- public boolean matches (Node node ) {
186-
187- if (node .getNodeType () == Node .ELEMENT_NODE && matchValue (((Element )node ).getAttribute (attributeName ))) {
188- return true ;
213+ public boolean matches (final Node node ) {
214+ final String attrValue ;
215+ if (attributeName .hasNamespace ()) {
216+ attrValue = ((Element ) node ).getAttributeNS (attributeName .getNamespaceURI (), attributeName .getLocalPart ());
217+ } else {
218+ attrValue = ((Element ) node ).getAttribute (attributeName .getLocalPart ());
189219 }
190220
191- return false ;
221+ return node .getNodeType () == Node .ELEMENT_NODE
222+ && matchValue (attrValue );
223+
192224 }
193225
194226 private boolean matchValue (String testValue ) {
@@ -365,7 +397,7 @@ public boolean find(Predicate predicate) {
365397
366398 if (qname .getNameType () == ElementValue .ATTRIBUTE
367399 && operator .equals (this .operator )
368- && qname .equals (this . attribute )
400+ && qname .equals (attributeName )
369401 && valueTypeMatches
370402 && foundValue .equals (requiredValue )) {
371403
0 commit comments