【问题标题】:XMLOutputStream, repairing namespaces, and attributes without namespacesXMLOutputStream,修复命名空间和没有命名空间的属性
【发布时间】:2011-03-05 09:03:23
【问题描述】:

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

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。

【问题讨论】:

    标签: java xml namespaces xml-namespaces stax


    【解决方案1】:

    我认为你必须告诉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.6.0_18 中的问题。
    • 或者我刚下载的1.6.0_20。
    • 啊,更正。您的代码确实有效,但不仅仅是默认命名空间有所不同,而是使用 writeStartElement(nsURI, localname) 而不是 writeStartElement("", localname, nsURI)。谢谢!
    • 哦,是的,对不起,也许我的回答不是很清楚,但这就是我的意思。
    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-15
      • 1970-01-01
      • 2010-10-20
      • 2010-11-04
      • 2015-04-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多