Skip to content

Commit 29692c1

Browse files
committed
[bugfix] Correctly handle Attribute nodes in fn:path
1 parent a3ef53f commit 29692c1

File tree

1 file changed

+22
-31
lines changed
  • exist-core/src/main/java/org/exist/xquery/functions/fn

1 file changed

+22
-31
lines changed

exist-core/src/main/java/org/exist/xquery/functions/fn/FunPath.java

Lines changed: 22 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.exist.xquery.value.*;
3030
import org.w3c.dom.*;
3131

32+
import javax.annotation.Nullable;
3233
import java.util.LinkedList;
3334
import java.util.List;
3435

@@ -133,18 +134,27 @@ private static int getNodePosition(final Node node) {
133134
* @param values the path values
134135
*/
135136
private static void getPathValues(Node node, final List<String> values) {
136-
// get the owner element, if the specified node is an attribute node
137-
Node attributeNode;
138-
if (node.getNodeType() == Type.ATTRIBUTE) {
139-
attributeNode = node;
140-
node = ((Attr) node).getOwnerElement();
141-
} else {
142-
attributeNode = null;
143-
}
137+
@Nullable Node parent = node.getParentNode();
144138

145139
final StringBuilder value = new StringBuilder();
146-
final StringBuilder attributeValue = new StringBuilder();
147-
if (node.getNodeType() == Type.TEXT) {
140+
141+
if (node.getNodeType() == Type.ATTRIBUTE) {
142+
// For an attribute node, if the node is in no namespace,
143+
// @local, where local is the local part of the node name.
144+
// Otherwise, @Q{uri}local, where uri is the namespace URI of
145+
// the node name, and local is the local part of the node name.
146+
value.append('/');
147+
if (node.getNamespaceURI() != null) {
148+
value.append(String.format("@Q{%s}", node.getNamespaceURI()));
149+
} else {
150+
value.append('@');
151+
}
152+
value.append(node.getLocalName());
153+
154+
// attributes have an owner element - not a parent node!
155+
parent = ((Attr) node).getOwnerElement();
156+
157+
} else if (node.getNodeType() == Type.TEXT) {
148158
// For a text node: text()[position] where position is an integer
149159
// representing the position of the selected node among its text
150160
// node siblings
@@ -194,31 +204,12 @@ private static void getPathValues(Node node, final List<String> values) {
194204
}
195205
}
196206

197-
// For an attribute node, if the node is in no namespace,
198-
// @local, where local is the local part of the node name.
199-
// Otherwise, @Q{uri}local, where uri is the namespace URI of
200-
// the node name, and local is the local part of the node name.
201-
if (attributeNode != null) {
202-
attributeValue.append('/');
203-
if (attributeNode.getNamespaceURI() != null) {
204-
attributeValue.append(String.format("@Q{%s}", attributeNode.getNamespaceURI()));
205-
} else {
206-
attributeValue.append('@');
207-
}
208-
attributeValue.append(attributeNode.getLocalName());
209-
node = attributeNode;
210-
}
211-
212-
if (node.getParentNode() != null) {
213-
getPathValues(node.getParentNode(), values);
207+
if (parent != null) {
208+
getPathValues(parent, values);
214209
}
215210

216211
if (value.toString().length() > 0) {
217212
values.add(value.toString());
218213
}
219-
220-
if (attributeValue.toString().length() > 0) {
221-
values.add(attributeValue.toString());
222-
}
223214
}
224215
}

0 commit comments

Comments
 (0)