1

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

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

伍德斯托克斯的回答:

<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。

4

2 回答 2

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”

于 2010-06-18T12:11:30.900 回答
1

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

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

据我所知,JDK 版本的问题是某些版本假定属性实际上确实使用了默认命名空间;这就是为什么添加了虚假的 'xmlns=""' 的原因。这是不必要的。

于 2010-08-10T20:16:53.120 回答