XMLOutputStream,修复名称空间和没有名称空间的属性

时间:2010-06-18 10:40:55

标签: java xml namespaces xml-namespaces stax

一个简单的任务:写一个元素两个属性:

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的回答:

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

JDK 6回答:

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

什么?!

此外,如果我们在元素中添加前缀:

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

JDK 6不再尝试发出xmlns =“”:

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

如果我们删除一个属性(即只有一个属性)就可以了。

我很确定这是JDK 6中的一个错误。我是对的吗?任何人都可以建议一个可以让两个图书馆(和其他人)都满意的工作吗?如果能帮助我,我不想要woodstox。

2 个答案:

答案 0 :(得分:2)

我认为你必须告诉XMLStreamWriter什么是默认命名空间,然后在添加元素时使用它:

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();

上面的代码给出了这个输出:

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

使用java版“1.6.0_20”

答案 1 :(得分:1)

我的建议是永远不要依赖于2参数版本的writeAttribute(),因为它应该输出的确切定义是不明确的:它应该使用命名空间“”(又名“无命名空间”)或者其他什么是当前默认名称空间这尤其令人困惑,因为根据XML规范,属性永远不会使用默认命名空间(只有显式命名空间)。因此可以说所有表达的行为都可以被认为是正确的;但显然他们不可能都是。它只是Stax API没有正确定义(AFAIK)真正的答案应该是什么(这很糟糕)。

所以:只需指定属性应该使用的命名空间(“”或null都适用于“无命名空间”),事情应该更好。

据我所知,JDK版本的问题在于某些版本假设属性确实使用默认命名空间;这就是为什么添加虚假'xmlns =“”'的原因。没必要。