Search code examples
javaxmlnamespacesxml-namespacesstax

XMLOutputStream, repairing namespaces, and attributes without namespaces


A simple task: write an element two attributes:

String nsURI = "http://example.com/";
XMLOutputFactory outF = XMLOutputFactory.newFactory();
outF.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, true);
XMLStreamWriter out = outF.createXMLStreamWriter(System.out);
out.writeStartElement(XMLConstants.DEFAULT_NS_PREFIX, "element", nsURI);
out.writeAttribute("attribute", "value");
out.writeAttribute("attribute2", "value");
out.writeEndElement();
out.close();

Woodstox's answer:

<element xmlns="http://example.com/" attribute="value" attribute2="value"></element>

JDK 6 answer:

<zdef-1905523464:element xmlns="" xmlns:zdef-1905523464="http://example.com/" attribute="value" attribute2="value"></zdef-1905523464:element>

What?!

Further, if we add a prefix to the element:

out.writeStartElement("ns", "element", nsURI);

JDK 6 no longer attempts to emit xmlns="":

<ns:element xmlns:ns="http://example.com/" attribute="value" attribute2="value"></ns:element>

And if we drop an attribute (i.e. only have one) it's fine.

I'm fairly sure this is a bug in JDK 6. Am I right? And could anyone suggest a work around that will keep both libraries (and any others) happy? I don't want to require woodstox if I can help it.


Solution

  • I think you must tell the XMLStreamWriter what is the default namespace, and then use it when adding elements:

    String nsURI = "http://example.com/";
    XMLOutputFactory outF = XMLOutputFactory.newFactory();
    outF.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, true);
    XMLStreamWriter out = outF.createXMLStreamWriter(System.out);
    out.setDefaultNamespace(nsURI);
    out.writeStartElement(nsURI, "element");
    out.writeAttribute("attribute", "value");
    out.writeAttribute("attribute2", "value");
    out.writeEndElement();
    out.close();
    

    The above code gives me this output:

    <element xmlns="http://example.com/" 
        attribute="value" attribute2="value"></element>
    

    with java version "1.6.0_20"