2010-06-18 155 views
1

一个简单的任务:写一个元素的两个属性:XMLOutputStream,修复名称空间和属性没有命名空间

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

我认为你必须告诉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”

+0

您之前是否得到过损坏的输出?这并不能解决1.6.0_18中的问题。我刚刚下载的 – user205512 2010-06-18 12:21:10

+0

或1.6.0_20。 – user205512 2010-06-18 12:47:34

+0

是的,我得到使用您的原始代码 – MarcoS 2010-06-18 12:50:26

1

我的建议是永远不要依赖writeAttribute()的双参数版本,因为定义它应该输出的内容不清楚:sh它应该使用命名空间“”(又名“无命名空间”)或任何当前的默认命名空间?这是特别令人困惑的,因为按照XML规范,属性从不使用默认名称空间(只有明确的名称空间)。所以可以说所有表达的行为都可以被看作是正确的;但显然他们不可能都是。这只是Stax API没有正确定义(AFAIK)真正的答案应该是什么(这很糟糕)。所以:只需指定属性应该使用的名称空间(“”或null都适用于“无名称空间”),并且事情应该更好。

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