diff --git a/exist-core/pom.xml b/exist-core/pom.xml
index de72cfe9b4..330179a94d 100644
--- a/exist-core/pom.xml
+++ b/exist-core/pom.xml
@@ -803,6 +803,7 @@
src/test/resources/log4j2.xml
src/test/resources/standalone-webapp/WEB-INF/web.xml
src/main/xjb/rest-api.xjb
+ src/test/xquery/base-uri.xql
src/test/xquery/parenthesizedLocationStep.xml
src/test/xquery/tail-recursion.xml
src/test/xquery/maps/maps.xqm
@@ -893,6 +894,7 @@
src/main/java/org/exist/dom/QName.java
src/main/java/org/exist/dom/memtree/AbstractCharacterData.java
src/main/java/org/exist/dom/memtree/AttrImpl.java
+ src/main/java/org/exist/dom/memtree/CommentImpl.java
src/main/java/org/exist/dom/memtree/DocumentBuilderReceiver.java
src/main/java/org/exist/dom/memtree/DocumentImpl.java
src/test/java/org/exist/dom/memtree/DocumentImplTest.java
@@ -923,6 +925,7 @@
src/main/java/org/exist/dom/persistent/EmptyNodeSet.java
src/main/java/org/exist/dom/persistent/LockToken.java
src/main/java/org/exist/dom/persistent/NewArrayNodeSet.java
+ src/main/java/org/exist/dom/persistent/NodeImpl.java
src/main/java/org/exist/dom/persistent/NodeProxy.java
src/main/java/org/exist/dom/persistent/NodeSet.java
src/test/java/org/exist/dom/persistent/NodeTest.java
@@ -1510,6 +1513,7 @@
src/test/resources/log4j2.xml
src/test/resources/standalone-webapp/WEB-INF/web.xml
src/main/xjb/rest-api.xjb
+ src/test/xquery/base-uri.xql
src/test/xquery/binary-value.xqm
src/test/xquery/instance-of.xqm
src/test/xquery/operator-mapping.xqm
@@ -1612,6 +1616,7 @@
src/main/java/org/exist/dom/QName.java
src/main/java/org/exist/dom/memtree/AbstractCharacterData.java
src/main/java/org/exist/dom/memtree/AttrImpl.java
+ src/main/java/org/exist/dom/memtree/CommentImpl.java
src/main/java/org/exist/dom/memtree/DocumentBuilderReceiver.java
src/main/java/org/exist/dom/memtree/DocumentImpl.java
src/test/java/org/exist/dom/memtree/DocumentImplTest.java
@@ -1650,6 +1655,7 @@
src/main/java/org/exist/dom/persistent/EmptyNodeSet.java
src/main/java/org/exist/dom/persistent/LockToken.java
src/main/java/org/exist/dom/persistent/NewArrayNodeSet.java
+ src/main/java/org/exist/dom/persistent/NodeImpl.java
src/main/java/org/exist/dom/persistent/NodeProxy.java
src/main/java/org/exist/dom/persistent/NodeSet.java
src/test/java/org/exist/dom/persistent/NodeTest.java
diff --git a/exist-core/src/main/java/org/exist/dom/memtree/AttrImpl.java b/exist-core/src/main/java/org/exist/dom/memtree/AttrImpl.java
index ba9dcf0479..b3341a7f13 100644
--- a/exist-core/src/main/java/org/exist/dom/memtree/AttrImpl.java
+++ b/exist-core/src/main/java/org/exist/dom/memtree/AttrImpl.java
@@ -53,6 +53,8 @@
import org.exist.xquery.value.Type;
import org.w3c.dom.*;
+import javax.annotation.Nullable;
+
public class AttrImpl extends NodeImpl implements Attr {
@@ -90,9 +92,9 @@ public int getType() {
}
@Override
- public String getBaseURI() {
- final Node parent = document.getNode(document.attrParent[nodeNumber]);
- if(parent == null) {
+ public @Nullable String getBaseURI() {
+ @Nullable final Node parent = document.getNode(document.attrParent[nodeNumber]);
+ if (parent == null) {
return null;
}
return parent.getBaseURI();
diff --git a/exist-core/src/main/java/org/exist/dom/memtree/CommentImpl.java b/exist-core/src/main/java/org/exist/dom/memtree/CommentImpl.java
index 9438d5f760..b75eda3e7b 100644
--- a/exist-core/src/main/java/org/exist/dom/memtree/CommentImpl.java
+++ b/exist-core/src/main/java/org/exist/dom/memtree/CommentImpl.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -29,6 +53,8 @@
import org.w3c.dom.Comment;
import org.w3c.dom.Node;
+import javax.annotation.Nullable;
+
public class CommentImpl extends AbstractCharacterData implements Comment {
public CommentImpl(final DocumentImpl doc, final int nodeNumber) {
@@ -53,9 +79,9 @@ public AtomicValue atomize() throws XPathException {
}
@Override
- public String getBaseURI() {
- final Node parent = getParentNode();
- if(parent == null) {
+ public @Nullable String getBaseURI() {
+ @Nullable final Node parent = getParentNode();
+ if (parent == null) {
return null;
}
return parent.getBaseURI();
diff --git a/exist-core/src/main/java/org/exist/dom/memtree/DocumentImpl.java b/exist-core/src/main/java/org/exist/dom/memtree/DocumentImpl.java
index 9270b1652f..93b41a3f22 100644
--- a/exist-core/src/main/java/org/exist/dom/memtree/DocumentImpl.java
+++ b/exist-core/src/main/java/org/exist/dom/memtree/DocumentImpl.java
@@ -1657,26 +1657,28 @@ public XQueryContext getContext() {
}
@Override
- public String getBaseURI() {
- final Element el = getDocumentElement();
- if(el != null) {
+ public @Nullable String getBaseURI() {
+ @Nullable final Element el = getDocumentElement();
+ if (el != null) {
final String baseURI = getDocumentElement().getAttributeNS(Namespaces.XML_NS, "base");
- if(baseURI != null) {
+ if (!baseURI.isEmpty()) {
return baseURI;
}
}
- final String docURI = getDocumentURI();
- if(docURI != null) {
+
+ @Nullable final String docURI = getDocumentURI();
+ if (docURI != null) {
return docURI;
} else {
- if(context!=null && context.isBaseURIDeclared()) {
+ if (context != null && context.isBaseURIDeclared()) {
try {
return context.getBaseURI().getStringValue();
- } catch(final XPathException e) {
- //TODO : make something !
+ } catch (final XPathException e) {
+ // no-op
}
}
- return XmldbURI.EMPTY_URI.toString();
+
+ return null;
}
}
diff --git a/exist-core/src/main/java/org/exist/dom/memtree/ElementImpl.java b/exist-core/src/main/java/org/exist/dom/memtree/ElementImpl.java
index ab1b674080..260f69196b 100644
--- a/exist-core/src/main/java/org/exist/dom/memtree/ElementImpl.java
+++ b/exist-core/src/main/java/org/exist/dom/memtree/ElementImpl.java
@@ -61,6 +61,7 @@
import org.exist.xquery.value.ValueSequence;
import org.w3c.dom.*;
+import javax.annotation.Nullable;
import javax.xml.XMLConstants;
import java.util.HashMap;
import java.util.HashSet;
@@ -619,18 +620,18 @@ public int getItemType() {
}
@Override
- public String getBaseURI() {
- final XmldbURI baseURI = calculateBaseURI();
- if(baseURI != null) {
+ public @Nullable String getBaseURI() {
+ @Nullable final XmldbURI baseURI = calculateBaseURI();
+ if (baseURI != null) {
return baseURI.toString();
}
- return "";//UNDERSTAND: is it ok?
+ return null;
}
// NOTE(AR) please keep in sync with org.exist.dom.persistent.ElementImpl
- private XmldbURI calculateBaseURI() {
- XmldbURI baseURI = null;
+ private @Nullable XmldbURI calculateBaseURI() {
+ @Nullable XmldbURI baseURI = null;
final String nodeBaseURI = getAttributeNS(Namespaces.XML_NS, "base");
if (!nodeBaseURI.isEmpty()) {
@@ -648,27 +649,32 @@ private XmldbURI calculateBaseURI() {
if (parent != -1) {
if (nodeBaseURI.isEmpty()) {
- baseURI = ((ElementImpl) document.getNode(parent))
- .calculateBaseURI();
+ baseURI = ((ElementImpl) document.getNode(parent)).calculateBaseURI();
} else {
- final XmldbURI parentsBaseURI = ((ElementImpl) document.getNode(parent)).calculateBaseURI();
- if (parentsBaseURI.toString().endsWith("/") || !parentsBaseURI.toString().contains("/")) {
- baseURI = parentsBaseURI.append(baseURI);
+ @Nullable final XmldbURI parentsBaseURI = ((ElementImpl) document.getNode(parent)).calculateBaseURI();
+ if (parentsBaseURI == null) {
+ baseURI = null;
} else {
- // there is a filename, remove it
- baseURI = parentsBaseURI.removeLastSegment().append(baseURI);
+ if (parentsBaseURI.toString().endsWith("/") || !parentsBaseURI.toString().contains("/")) {
+ baseURI = parentsBaseURI.append(baseURI);
+ } else {
+ // there is a filename, remove it
+ baseURI = parentsBaseURI.removeLastSegment().append(baseURI);
+ }
}
}
} else {
- if (nodeBaseURI.isEmpty()) {
- return XmldbURI.create(getOwnerDocument().getBaseURI(), false);
+ @Nullable final String docBaseURI = getOwnerDocument().getBaseURI();
+ if (docBaseURI == null) {
+ baseURI = null;
+ } else if (nodeBaseURI.isEmpty()) {
+ baseURI = XmldbURI.create(docBaseURI, false);
} else if (nodeNumber != 1) {
- final String docBaseURI = getOwnerDocument().getBaseURI();
if (docBaseURI.endsWith("/")) {
- baseURI = XmldbURI.create(getOwnerDocument().getBaseURI(), false);
+ baseURI = XmldbURI.create(docBaseURI, false);
baseURI.append(baseURI);
} else {
- baseURI = XmldbURI.create(getOwnerDocument().getBaseURI(), false);
+ baseURI = XmldbURI.create(docBaseURI, false);
baseURI = baseURI.removeLastSegment();
baseURI.append(baseURI);
}
diff --git a/exist-core/src/main/java/org/exist/dom/memtree/NodeImpl.java b/exist-core/src/main/java/org/exist/dom/memtree/NodeImpl.java
index 0f5cbfa870..82cd0ddd60 100644
--- a/exist-core/src/main/java/org/exist/dom/memtree/NodeImpl.java
+++ b/exist-core/src/main/java/org/exist/dom/memtree/NodeImpl.java
@@ -770,7 +770,7 @@ public void removeDuplicates() {
}
@Override
- public String getBaseURI() {
+ public @Nullable String getBaseURI() {
return null;
}
diff --git a/exist-core/src/main/java/org/exist/dom/memtree/ProcessingInstructionImpl.java b/exist-core/src/main/java/org/exist/dom/memtree/ProcessingInstructionImpl.java
index 913682b992..4f8a97cc6f 100644
--- a/exist-core/src/main/java/org/exist/dom/memtree/ProcessingInstructionImpl.java
+++ b/exist-core/src/main/java/org/exist/dom/memtree/ProcessingInstructionImpl.java
@@ -57,6 +57,8 @@
import org.w3c.dom.Node;
import org.w3c.dom.ProcessingInstruction;
+import javax.annotation.Nullable;
+
public class ProcessingInstructionImpl extends NodeImpl implements ProcessingInstruction {
@@ -102,37 +104,12 @@ public void setData(final String data) throws DOMException {
}
@Override
- public String getBaseURI() {
- String baseURI = "";
- int parent = -1;
- int test = document.getParentNodeFor(nodeNumber);
-
- if(document.nodeKind[test] != Node.DOCUMENT_NODE) {
- parent = test;
- }
-
- // fixme! Testa med 0/ljo
- while((parent != -1) && (document.getNode(parent).getBaseURI() != null)) {
-
- if(baseURI.isEmpty()) {
- baseURI = document.getNode(parent).getBaseURI();
- } else {
- baseURI = document.getNode(parent).getBaseURI() + "/" + baseURI;
- }
-
- test = document.getParentNodeFor(parent);
-
- if(document.nodeKind[test] == Node.DOCUMENT_NODE) {
- return (baseURI);
- } else {
- parent = test;
- }
- }
-
- if(baseURI.isEmpty()) {
- baseURI = getOwnerDocument().getBaseURI();
+ public @Nullable String getBaseURI() {
+ @Nullable final Node parent = getParentNode();
+ if (parent == null) {
+ return null;
}
- return (baseURI);
+ return parent.getBaseURI();
}
@Override
diff --git a/exist-core/src/main/java/org/exist/dom/memtree/TextImpl.java b/exist-core/src/main/java/org/exist/dom/memtree/TextImpl.java
index 55aa7ad886..11efd59387 100644
--- a/exist-core/src/main/java/org/exist/dom/memtree/TextImpl.java
+++ b/exist-core/src/main/java/org/exist/dom/memtree/TextImpl.java
@@ -24,8 +24,11 @@
import org.exist.xquery.Expression;
import org.exist.xquery.value.Type;
import org.w3c.dom.DOMException;
+import org.w3c.dom.Node;
import org.w3c.dom.Text;
+import javax.annotation.Nullable;
+
public class TextImpl extends AbstractCharacterData implements Text {
@@ -42,6 +45,15 @@ public int getItemType() {
return Type.TEXT;
}
+ @Override
+ public @Nullable String getBaseURI() {
+ @Nullable final Node parent = getParentNode();
+ if (parent == null) {
+ return null;
+ }
+ return parent.getBaseURI();
+ }
+
@Override
public Text splitText(final int offset) throws DOMException {
return null;
diff --git a/exist-core/src/main/java/org/exist/dom/persistent/AttrImpl.java b/exist-core/src/main/java/org/exist/dom/persistent/AttrImpl.java
index a829fb5639..6f2dff640c 100644
--- a/exist-core/src/main/java/org/exist/dom/persistent/AttrImpl.java
+++ b/exist-core/src/main/java/org/exist/dom/persistent/AttrImpl.java
@@ -60,6 +60,7 @@
import org.exist.xquery.Expression;
import org.w3c.dom.*;
+import javax.annotation.Nullable;
import javax.xml.XMLConstants;
import static java.nio.charset.StandardCharsets.UTF_8;
@@ -421,9 +422,9 @@ public boolean isId() {
}
@Override
- public String getBaseURI() {
- final Element e = getOwnerElement();
- if(e != null) {
+ public @Nullable String getBaseURI() {
+ @Nullable final Element e = getOwnerElement();
+ if (e != null) {
return e.getBaseURI();
}
return null;
diff --git a/exist-core/src/main/java/org/exist/dom/persistent/CommentImpl.java b/exist-core/src/main/java/org/exist/dom/persistent/CommentImpl.java
index 99d7ec3c7a..9ad5f108cb 100644
--- a/exist-core/src/main/java/org/exist/dom/persistent/CommentImpl.java
+++ b/exist-core/src/main/java/org/exist/dom/persistent/CommentImpl.java
@@ -53,6 +53,8 @@
import org.w3c.dom.Comment;
import org.w3c.dom.Node;
+import javax.annotation.Nullable;
+
import static java.nio.charset.StandardCharsets.UTF_8;
public class CommentImpl extends AbstractCharacterData implements Comment {
@@ -86,6 +88,16 @@ public String toString() {
return "";
}
+ @Override
+ public @Nullable String getBaseURI() {
+ @Nullable final Node parent = getParentNode();
+ if (parent != null) {
+ return parent.getBaseURI();
+ } else {
+ return null;
+ }
+ }
+
/**
* Serializes a (persistent DOM) Comment to a byte array
*
diff --git a/exist-core/src/main/java/org/exist/dom/persistent/ElementImpl.java b/exist-core/src/main/java/org/exist/dom/persistent/ElementImpl.java
index c58e77d777..24e3f489d4 100644
--- a/exist-core/src/main/java/org/exist/dom/persistent/ElementImpl.java
+++ b/exist-core/src/main/java/org/exist/dom/persistent/ElementImpl.java
@@ -2000,18 +2000,18 @@ public void setIdAttributeNode(final Attr idAttr, final boolean isId) throws DOM
}
@Override
- public String getBaseURI() {
- final XmldbURI baseURI = calculateBaseURI();
- if(baseURI != null) {
+ public @Nullable String getBaseURI() {
+ @Nullable final XmldbURI baseURI = calculateBaseURI();
+ if (baseURI != null) {
return baseURI.toString();
}
- return ""; //UNDERSTAND: is it ok?
+ return null;
}
// NOTE(AR) please keep in sync with org.exist.dom.memtree.ElementImpl
private XmldbURI calculateBaseURI() {
- XmldbURI baseURI = null;
+ @Nullable XmldbURI baseURI = null;
final String nodeBaseURI = getAttributeNS(Namespaces.XML_NS, "base");
if (!nodeBaseURI.isEmpty()) {
@@ -2022,28 +2022,35 @@ private XmldbURI calculateBaseURI() {
}
final IStoredNode> parent = getParentStoredNode();
+
if (parent != null) {
if (nodeBaseURI.isEmpty()) {
baseURI = ((ElementImpl) parent).calculateBaseURI();
} else {
- final XmldbURI parentsBaseURI = ((ElementImpl) parent).calculateBaseURI();
- if (parentsBaseURI.toString().endsWith("/") || !parentsBaseURI.toString().contains("/")) {
- baseURI = parentsBaseURI.append(baseURI);
+ @Nullable final XmldbURI parentsBaseURI = ((ElementImpl) parent).calculateBaseURI();
+ if (parentsBaseURI == null) {
+ baseURI = null;
} else {
- // there is a filename, remove it
- baseURI = parentsBaseURI.removeLastSegment().append(baseURI);
+ if (parentsBaseURI.toString().endsWith("/") || !parentsBaseURI.toString().contains("/")) {
+ baseURI = parentsBaseURI.append(baseURI);
+ } else {
+ // there is a filename, remove it
+ baseURI = parentsBaseURI.removeLastSegment().append(baseURI);
+ }
}
}
} else {
- if (nodeBaseURI.isEmpty()) {
- return XmldbURI.create(getOwnerDocument().getBaseURI(), false);
+ @Nullable final String docBaseURI = getOwnerDocument().getBaseURI();
+ if (docBaseURI == null) {
+ baseURI = null;
+ } else if (nodeBaseURI.isEmpty()) {
+ baseURI = XmldbURI.create(docBaseURI, false);
} else {
- final String docBaseURI = getOwnerDocument().getBaseURI();
if (docBaseURI.endsWith("/")) {
- baseURI = XmldbURI.create(getOwnerDocument().getBaseURI(), false);
+ baseURI = XmldbURI.create(docBaseURI, false);
baseURI.append(baseURI);
} else {
- baseURI = XmldbURI.create(getOwnerDocument().getBaseURI(), false);
+ baseURI = XmldbURI.create(docBaseURI, false);
baseURI = baseURI.removeLastSegment();
baseURI.append(baseURI);
}
diff --git a/exist-core/src/main/java/org/exist/dom/persistent/NodeImpl.java b/exist-core/src/main/java/org/exist/dom/persistent/NodeImpl.java
index 893f88b534..354dc98a63 100644
--- a/exist-core/src/main/java/org/exist/dom/persistent/NodeImpl.java
+++ b/exist-core/src/main/java/org/exist/dom/persistent/NodeImpl.java
@@ -1,4 +1,28 @@
/*
+ * Elemental
+ * Copyright (C) 2024, Evolved Binary Ltd
+ *
+ * admin@evolvedbinary.com
+ * https://www.evolvedbinary.com | https://www.elemental.xyz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ * The original license header is included below.
+ *
+ * =====================================================================
+ *
* eXist-db Open Source Native XML Database
* Copyright (C) 2001 The eXist-db Authors
*
@@ -30,6 +54,7 @@
import org.exist.xquery.Expression;
import org.w3c.dom.*;
+import javax.annotation.Nullable;
import javax.xml.XMLConstants;
public abstract class NodeImpl implements INode {
@@ -187,8 +212,8 @@ public void normalize() {
}
@Override
- public String getBaseURI() {
- throw unsupported();
+ public @Nullable String getBaseURI() {
+ return null;
}
@Override
diff --git a/exist-core/src/main/java/org/exist/dom/persistent/ProcessingInstructionImpl.java b/exist-core/src/main/java/org/exist/dom/persistent/ProcessingInstructionImpl.java
index 1f16448e98..6a42f27b0e 100644
--- a/exist-core/src/main/java/org/exist/dom/persistent/ProcessingInstructionImpl.java
+++ b/exist-core/src/main/java/org/exist/dom/persistent/ProcessingInstructionImpl.java
@@ -55,6 +55,8 @@
import org.w3c.dom.Node;
import org.w3c.dom.ProcessingInstruction;
+import javax.annotation.Nullable;
+
import static java.nio.charset.StandardCharsets.UTF_8;
/**
@@ -148,13 +150,10 @@ public void setData(final String data) {
this.data = data;
}
- /**
- * ? @see org.w3c.dom.Node#getBaseURI()
- */
@Override
- public String getBaseURI() {
- final StoredNode parent = getParentStoredNode();
- if(parent != null) {
+ public @Nullable String getBaseURI() {
+ @Nullable final StoredNode parent = getParentStoredNode();
+ if (parent != null) {
return parent.getBaseURI();
} else {
return getOwnerDocument().getBaseURI();
diff --git a/exist-core/src/main/java/org/exist/dom/persistent/TextImpl.java b/exist-core/src/main/java/org/exist/dom/persistent/TextImpl.java
index 7887e0b0ce..6c9d9c8971 100644
--- a/exist-core/src/main/java/org/exist/dom/persistent/TextImpl.java
+++ b/exist-core/src/main/java/org/exist/dom/persistent/TextImpl.java
@@ -58,6 +58,8 @@
import org.w3c.dom.Text;
import org.w3c.dom.UserDataHandler;
+import javax.annotation.Nullable;
+
/**
* TextImpl.java
*
@@ -175,9 +177,9 @@ public Text splitText(final int offset) throws DOMException {
}
@Override
- public String getBaseURI() {
- final Node parent = getParentNode();
- if(parent != null) {
+ public @Nullable String getBaseURI() {
+ @Nullable final Node parent = getParentNode();
+ if (parent != null) {
return parent.getBaseURI();
} else {
return null;
diff --git a/exist-core/src/main/java/org/exist/xquery/functions/fn/FunBaseURI.java b/exist-core/src/main/java/org/exist/xquery/functions/fn/FunBaseURI.java
index b23870a6e6..c2b7291850 100644
--- a/exist-core/src/main/java/org/exist/xquery/functions/fn/FunBaseURI.java
+++ b/exist-core/src/main/java/org/exist/xquery/functions/fn/FunBaseURI.java
@@ -50,6 +50,7 @@
import org.exist.xquery.value.*;
import org.w3c.dom.Node;
+import javax.annotation.Nullable;
import java.net.URI;
import java.net.URISyntaxException;
@@ -172,7 +173,7 @@ public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathExce
final boolean hasContextBaseURI = context.isBaseURIDeclared();
// "" when not set, can be null
- final String nodeBaseURI = node.getBaseURI();
+ @Nullable final String nodeBaseURI = node.getBaseURI();
final boolean hasNodeBaseURI = notNullOrEmptyOrWs(nodeBaseURI);
try {
diff --git a/exist-core/src/test/java/org/exist/dom/memtree/DocumentImplTest.java b/exist-core/src/test/java/org/exist/dom/memtree/DocumentImplTest.java
index 7fdb1113b9..0dcc7b2055 100644
--- a/exist-core/src/test/java/org/exist/dom/memtree/DocumentImplTest.java
+++ b/exist-core/src/test/java/org/exist/dom/memtree/DocumentImplTest.java
@@ -206,6 +206,36 @@ public void testGetInScopePrefix() throws IOException, ParserConfigurationExcept
assertEquals(Namespaces.XHTML_NS, namespaceUri);
}
+ @Test
+ public void getBaseURI_withDocumentURI() throws IOException, SAXException, ParserConfigurationException {
+ final DocumentImpl doc;
+ try(final InputStream is = new UnsynchronizedByteArrayInputStream("".getBytes(UTF_8))) {
+ doc = parseExist(is);
+ }
+ doc.setDocumentURI("file:///intranet/xsl/template.xsl");
+ assertEquals("file:///intranet/xsl/template.xsl", doc.getBaseURI());
+ }
+
+ @Test
+ public void getBaseURI_prefersXmlBaseOnRoot() throws IOException, SAXException, ParserConfigurationException {
+ final DocumentImpl doc;
+ try(final InputStream is = new UnsynchronizedByteArrayInputStream(
+ "".getBytes(UTF_8))) {
+ doc = parseExist(is);
+ }
+ doc.setDocumentURI("file:///intranet/xsl/template.xsl");
+ assertEquals("http://example.org/", doc.getBaseURI());
+ }
+
+ @Test
+ public void getBaseURI_noDocumentURI() throws IOException, SAXException, ParserConfigurationException {
+ final DocumentImpl doc;
+ try(final InputStream is = new UnsynchronizedByteArrayInputStream("".getBytes(UTF_8))) {
+ doc = parseExist(is);
+ }
+ assertNull("", doc.getBaseURI());
+ }
+
private Document parseXerces(final InputStream is) throws ParserConfigurationException, SAXException, IOException {
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
diff --git a/exist-core/src/test/xquery/base-uri.xql b/exist-core/src/test/xquery/base-uri.xql
index 51b46bb64f..3aff020995 100644
--- a/exist-core/src/test/xquery/base-uri.xql
+++ b/exist-core/src/test/xquery/base-uri.xql
@@ -1,4 +1,28 @@
(:
+ : Elemental
+ : Copyright (C) 2024, Evolved Binary Ltd
+ :
+ : admin@evolvedbinary.com
+ : https://www.evolvedbinary.com | https://www.elemental.xyz
+ :
+ : This library is free software; you can redistribute it and/or
+ : modify it under the terms of the GNU Lesser General Public
+ : License as published by the Free Software Foundation; version 2.1.
+ :
+ : This library is distributed in the hope that it will be useful,
+ : but WITHOUT ANY WARRANTY; without even the implied warranty of
+ : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ : Lesser General Public License for more details.
+ :
+ : You should have received a copy of the GNU Lesser General Public
+ : License along with this library; if not, write to the Free Software
+ : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ :
+ : NOTE: Parts of this file contain code from 'The eXist-db Authors'.
+ : The original license header is included below.
+ :
+ : =====================================================================
+ :
: eXist-db Open Source Native XML Database
: Copyright (C) 2001 The eXist-db Authors
:
@@ -100,7 +124,7 @@ function baseuri:root() {
};
declare
- %test:assertEquals("http://example.org/a/","http://example.org/b/","http://example.org/c/","/yy","zz")
+ %test:assertEquals("http://example.org/a/","http://example.org/b/","http://example.org/c/","/yy")
function baseuri:sub1() {
for $sub in $baseuri:DOCUMENT//sub
return base-uri($sub)