Skip to content

Commit 2e946f8

Browse files
committed
Fixes #138 - backward ccompatibility issue with JDOM 1.x DOM
JDOM 1.x managed to handle badly-built DOM documents that had implied namespaces in place.
1 parent f4c6d0f commit 2e946f8

File tree

2 files changed

+42
-3
lines changed

2 files changed

+42
-3
lines changed

core/src/java/org/jdom2/input/DOMBuilder.java

+12-2
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ private void buildTree(org.w3c.dom.Node node,
342342
// Get attribute's namespace
343343
Namespace attNS = null;
344344
String attURI = att.getNamespaceURI();
345-
if (attURI == null || NS_URI_DEFAULT.equals(attURI)) {
345+
if (attPrefix.isEmpty() && (attURI == null || NS_URI_DEFAULT.equals(attURI))) {
346346
attNS = Namespace.NO_NAMESPACE;
347347
} else {
348348
// various conditions can lead here.
@@ -361,7 +361,17 @@ private void buildTree(org.w3c.dom.Node node,
361361
// then we re-declare it. If redeclaring it screws up
362362
// other attributes in this Element, then the DOM
363363
// was broken to start with.
364-
attNS = Namespace.getNamespace(attPrefix, attURI);
364+
if (attURI == null) {
365+
// this can happen when the DOM is created
366+
// without being namespace aware. we have a
367+
// prefix, but the URI is not embedded in
368+
// the Attribute itself. It must be declared
369+
// on the element somewhere....
370+
// https://github.com/hunterhacker/jdom/issues/138
371+
attNS = element.getNamespace(attPrefix);
372+
} else {
373+
attNS = Namespace.getNamespace(attPrefix, attURI);
374+
}
365375
} else {
366376
// OK, no prefix.
367377
// must be a defaulted value from an XSD.

test/src/java/org/jdom2/test/cases/input/TestDOMBuilder.java

+30-1
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,15 @@
88
import java.io.CharArrayWriter;
99
import java.io.IOException;
1010

11-
import org.junit.Test;
11+
import javax.xml.parsers.DocumentBuilderFactory;
1212

13+
import org.junit.Test;
14+
import org.jdom2.Attribute;
1315
import org.jdom2.DefaultJDOMFactory;
1416
import org.jdom2.DocType;
1517
import org.jdom2.Document;
1618
import org.jdom2.Element;
19+
import org.jdom2.Namespace;
1720
import org.jdom2.input.DOMBuilder;
1821
import org.jdom2.input.SAXBuilder;
1922
import org.jdom2.input.sax.XMLReaders;
@@ -71,6 +74,32 @@ public void testXSDDocument() {
7174
checkDOM("/xsdcomplex/input.xml", true);
7275
}
7376

77+
@Test
78+
public void testNoNamespaceDOM() throws Exception {
79+
// https://github.com/hunterhacker/jdom/issues/138
80+
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
81+
org.w3c.dom.Document doc = dbFactory.newDocumentBuilder().newDocument();
82+
doc.setXmlVersion("1.0");
83+
84+
org.w3c.dom.Element root = doc.createElement("Document");
85+
86+
root.setAttribute("xmlns", "urn:iso:foo");
87+
root.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
88+
root.setAttribute("xsi:schemaLocation", "urn:iso:foo bar.xsd");
89+
doc.appendChild(root);
90+
91+
// The above is a badly-formed DOM document without the correct
92+
// namespaceing. The second attribute should use root.setAttributeNS
93+
DOMBuilder dbuilder = new DOMBuilder();
94+
Document jdoc = dbuilder.build(doc);
95+
96+
Namespace xsi = Namespace.getNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
97+
Attribute att = jdoc.getRootElement().getAttribute("schemaLocation", xsi);
98+
assertTrue(att != null);
99+
assertTrue("xsi".equals(att.getNamespacePrefix()));
100+
101+
}
102+
74103
private void checkDOM(String resname, boolean xsdvalidate) {
75104
try {
76105
org.w3c.dom.Document domdoc = HelpTestDOMBuilder.getDocument(resname, xsdvalidate);

0 commit comments

Comments
 (0)