Repository navigation
AbstractDOMOutputProcessor doesn't explicitly set namespace of xmlns attributes #115
Description
Hello,
The default implementation of DOMOutputProcessor generates xmlns attributes without setting the namespace. On the JAXP in Oracle Java 1.7 this means the generated Attrs have a null Namespace URI. This is causing us problems when serialising these Elements as part of a JAXB object (using EclipseLink MOXy - the Metro implementation is able to cope with it).
I'm not entirely sure if this is strictly a bug in JDOM or if the fault lies with JAXP for not inferring the Namespace URI on an element prefixed with "xmlns" - but it does mean the Documents coming from DOMOutputter don't look the same as a document coming from the built-in DocumentBuilderFactory.
Here's a JUnit test to reproduce the issue.
import org.jdom2.Element;
import org.jdom2.JDOMConstants;
import org.jdom2.input.DOMBuilder;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.DOMOutputter;
import org.junit.Test;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.StringReader;
import static org.junit.Assert.assertEquals;
public class DOMOutputterNamespaceTest
{
/**
* The XML document to test - this document
*/
private static final String XML = "<el xmlns:test=\"urn:test\" />";
/**
* Parse the XML using DOM
*
* @throws Exception
*/
@Test
public void testDocumentBuilderSource() throws Exception
{
org.w3c.dom.Element element = parseDOM(XML);
final String namespace = element.getAttributeNode("xmlns:test").getNamespaceURI();
assertEquals("DocumentBuilder output", JDOMConstants.NS_URI_XMLNS, namespace);
}
/**
* Parse the XML using JDOM, convert to DOM
*
* @throws Exception
*/
@Test
public void testJdomToDom() throws Exception
{
org.w3c.dom.Element element = jdomToDom(parseJDOM(XML)); // load JDOM and convert to DOM
final String namespace = element.getAttributeNode("xmlns:test").getNamespaceURI();
assertEquals("SAXBuilder->DOMOutputter output", JDOMConstants.NS_URI_XMLNS, namespace);
}
/**
* Parse the XML using DOM, then convert to JDOM and then finally back to DOM
*
* @throws Exception
*/
@Test
public void testDomToJdomToDom() throws Exception
{
org.w3c.dom.Element element = jdomToDom(domToJdom(parseDOM(XML))); // load DOM, convert to JDOM and back to DOM
final String namespace = element.getAttributeNode("xmlns:test").getNamespaceURI();
assertEquals("DocumentBuilder->DOMBuilder->DOMOutputter output", JDOMConstants.NS_URI_XMLNS, namespace);
}
private Element parseJDOM(String xml) throws Exception
{
final StringReader src = new StringReader(xml);
return new SAXBuilder().build(src).getRootElement();
}
private org.w3c.dom.Element parseDOM(String xml) throws Exception
{
InputSource src = new InputSource(new StringReader(xml));
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder documentBuilder = factory.newDocumentBuilder();
Document result = documentBuilder.parse(src);
return result.getDocumentElement();
}
/**
* Converts a JDOM Element to a DOM Element
*
* @param element
*
* @return
*
* @throws Exception
*/
private org.w3c.dom.Element jdomToDom(org.jdom2.Element element) throws Exception
{
return new DOMOutputter().output(element);
}
/**
* Converts a DOM Element to a JDOM Element
*
* @param element
*
* @return
*
* @throws Exception
*/
private org.jdom2.Element domToJdom(org.w3c.dom.Element element) throws Exception
{
final DOMBuilder builder = new DOMBuilder();
return builder.build(element);
}
}On our machines (Oracle Java 1.7, JDOM 2.0.4) the output is as follows:
testDocumentBuilderSource: pass
testJdomToDom: fail
java.lang.AssertionError: SAXBuilder->DOMOutputter output expected:<http://www.w3.org/2000/xmlns/> but was:<null>
testDomToJdomToDom: fail
java.lang.AssertionError: DocumentBuilder->DOMBuilder->DOMOutputter output expected:<http://www.w3.org/2000/xmlns/> but was:<null>
Activity
rolfl commentedon Apr 12, 2013
Well, that's a comprehensive issue report, and a suprising problem. Thanks. I will look in to it shortly.
petergeneric commentedon Apr 12, 2013
I've got a patch to AbstractDOMOutputProcessor that should work at petergeneric@c27a4fc and a unit test as part of petergeneric@2c32cc5 (it doesn't use the same structure as the other jdom unit tests though - added it in a separate commit for clarity)
rolfl commentedon Apr 12, 2013
I pulled your fixes right in - b174b37 and 25153ea . Thanks
Remove Base64 (we depend on Java 1.8 so can use the native Base64 imp…