Skip to content

Commit

Permalink
Fixes #138 - backward ccompatibility issue with JDOM 1.x DOM
Browse files Browse the repository at this point in the history
JDOM 1.x managed to handle badly-built DOM documents that had implied
namespaces in place.
  • Loading branch information
rolfl committed Feb 15, 2015
1 parent f4c6d0f commit 2e946f8
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 3 deletions.
14 changes: 12 additions & 2 deletions core/src/java/org/jdom2/input/DOMBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ private void buildTree(org.w3c.dom.Node node,
// Get attribute's namespace
Namespace attNS = null;
String attURI = att.getNamespaceURI();
if (attURI == null || NS_URI_DEFAULT.equals(attURI)) {
if (attPrefix.isEmpty() && (attURI == null || NS_URI_DEFAULT.equals(attURI))) {
attNS = Namespace.NO_NAMESPACE;
} else {
// various conditions can lead here.
Expand All @@ -361,7 +361,17 @@ private void buildTree(org.w3c.dom.Node node,
// then we re-declare it. If redeclaring it screws up
// other attributes in this Element, then the DOM
// was broken to start with.
attNS = Namespace.getNamespace(attPrefix, attURI);
if (attURI == null) {
// this can happen when the DOM is created
// without being namespace aware. we have a
// prefix, but the URI is not embedded in
// the Attribute itself. It must be declared
// on the element somewhere....
// https://github.com/hunterhacker/jdom/issues/138
attNS = element.getNamespace(attPrefix);
} else {
attNS = Namespace.getNamespace(attPrefix, attURI);
}
} else {
// OK, no prefix.
// must be a defaulted value from an XSD.
Expand Down
31 changes: 30 additions & 1 deletion test/src/java/org/jdom2/test/cases/input/TestDOMBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@
import java.io.CharArrayWriter;
import java.io.IOException;

import org.junit.Test;
import javax.xml.parsers.DocumentBuilderFactory;

import org.junit.Test;
import org.jdom2.Attribute;
import org.jdom2.DefaultJDOMFactory;
import org.jdom2.DocType;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.Namespace;
import org.jdom2.input.DOMBuilder;
import org.jdom2.input.SAXBuilder;
import org.jdom2.input.sax.XMLReaders;
Expand Down Expand Up @@ -71,6 +74,32 @@ public void testXSDDocument() {
checkDOM("/xsdcomplex/input.xml", true);
}

@Test
public void testNoNamespaceDOM() throws Exception {
// https://github.com/hunterhacker/jdom/issues/138
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
org.w3c.dom.Document doc = dbFactory.newDocumentBuilder().newDocument();
doc.setXmlVersion("1.0");

org.w3c.dom.Element root = doc.createElement("Document");

root.setAttribute("xmlns", "urn:iso:foo");
root.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
root.setAttribute("xsi:schemaLocation", "urn:iso:foo bar.xsd");
doc.appendChild(root);

// The above is a badly-formed DOM document without the correct
// namespaceing. The second attribute should use root.setAttributeNS
DOMBuilder dbuilder = new DOMBuilder();
Document jdoc = dbuilder.build(doc);

Namespace xsi = Namespace.getNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
Attribute att = jdoc.getRootElement().getAttribute("schemaLocation", xsi);
assertTrue(att != null);
assertTrue("xsi".equals(att.getNamespacePrefix()));

}

private void checkDOM(String resname, boolean xsdvalidate) {
try {
org.w3c.dom.Document domdoc = HelpTestDOMBuilder.getDocument(resname, xsdvalidate);
Expand Down

0 comments on commit 2e946f8

Please sign in to comment.