diff --git a/core/src/java/org/jdom2/input/DOMBuilder.java b/core/src/java/org/jdom2/input/DOMBuilder.java index 3ba27e54d..0a90e59ed 100644 --- a/core/src/java/org/jdom2/input/DOMBuilder.java +++ b/core/src/java/org/jdom2/input/DOMBuilder.java @@ -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. @@ -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. diff --git a/test/src/java/org/jdom2/test/cases/input/TestDOMBuilder.java b/test/src/java/org/jdom2/test/cases/input/TestDOMBuilder.java index f5c0875a9..803612121 100644 --- a/test/src/java/org/jdom2/test/cases/input/TestDOMBuilder.java +++ b/test/src/java/org/jdom2/test/cases/input/TestDOMBuilder.java @@ -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; @@ -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);