开发者

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-1905523开发者_开发技巧464="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.


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"


My suggestion would be to never rely on 2-argument version of writeAttribute(), since definition of what exactly it ought to output is not clear: should it use namespace "" (aka "no namespace") or whatever is the current default namespace? This is especially confusing since as per XML specification, attributes never use the default namespace (only explicit ones). So arguably all behaviors expressed can be seen as potentially correct; but obviously they can not all be. It's just Stax API does not properly define (AFAIK) what the real answer should be (which sucks).

So: just specify namespace that attribute should use ("" or null both work for "no namespace") and things should work better.

Problem with JDK version, as far as I know, is that some versions assumed that attributes did in fact use the default namespace; and that's why that bogus 'xmlns=""' was added. It is unnecessary.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜