在Java 8中,当使用Woodstox运行时,名称空间前缀会发生变化

时间:2016-04-22 21:05:56

标签: java xml java-8 xml-namespaces woodstox

我有一个简单的Java程序,如下所示,它读取一个xml文件并将其打印在控制台中:

FileInputStream in = new FileInputStream(new File("/tmp/test.xml"));
InputStreamReader streamReader = new InputStreamReader(in);
OMXMLParserWrapper builder = BuilderUtil.getBuilder(streamReader);

SOAPEnvelope envelope = (SOAPEnvelope)builder.getDocumentElement();
//the namespace prefix is OK here (java 7 and java 8)
System.out.println(envelope.getHeader().getChildrenWithLocalName("Ticket").next());

//but after the toString() method, the prefix has modified (java 7 = not change, java 8 = change)
//attribute mustUnderstand and role
System.out.println(envelope.toString());

XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope" xmlns:env="http://www.w3.org/2003/05/soap-envelope">
    <S:Header>
        <abc:Ticket xmlns:abc="somevalue" xmlns:uebernehmeAbschlussdatenXBRL="abcSomevalue" S:mustUnderstand="true" S:role="http://www.w3.org/2003/05/soap-envelope/role/next">
            <abc:value>long value</abc:value>
        </abc:Ticket>   
    </S:Header>
    <S:Body>    
        <sample>data</sample>
    </S:Body>
</S:Envelope>

当我使用 woodstox-core-asl-4.4.1,stax2-api-3.1.4 公理在Java 7中运行程序时,它运行正常。 但是当我在Java 8中运行相同的东西时,S:role和S:mustunderstand变为env:role和env:mustunderstand( S前缀变为env

如果我从程序中删除 woodstox-core-asl-4.4.1 stax2-api-3.1.4 ,它在Java 8中也能正常工作

我无法弄清楚这个问题。这是否意味着woodstox不支持Java 8或我错过了其他什么?

3 个答案:

答案 0 :(得分:2)

文档中的前缀Senv都映射到相同的名称空间URI http://www.w3.org/2003/05/soap-envelope

因此,即使序列化文档中的前缀发生了变化,它仍然等同于保留前缀的前缀。

(更改的原因可能是Java 8的DOM实现,类似于命名空间声明的不同排序。)

答案 1 :(得分:1)

这里要注意的一个基本事项是:使用envelope.toString()并不是真正可靠的测试方法,因为目前还不清楚究竟是什么打印。 Woodstox不会更改报告的前缀,因此它不太可能暴露不同的前缀:更可能的情况是Axiom构建信封并将给定名称空间URI的映射回到不同的前缀,假设有2个选项。

所以:我猜这是因为JDK更改与String哈希代码计算或HashMap条目的排序有关。假设存在2个具有不同前缀的等效命名空间,当Axiom请求给定命名空间URI的前缀时,两者的排序可能导致不同的匹配;毕竟,BOTH映射到相同的前缀,并且由于属性的排序(其名称空间前缀声明是特殊情况)在XML中是未定义的(即,没有排序),其中一个是有效的

如果没有Woodstox依赖,处理可能使用JDK嵌入式Stax解析器(sjsxp),并且对它进行排序可能是意外稳定的,或者使用非基于散列的机制。

答案 2 :(得分:0)

意外的前缀是由旧版本的Apache Axiom(1.2.11超过5年)中的问题引起的。您应该升级到1.2.15或更高版本。

Axiom曾经使用HashMap来存储名称空间声明;这可能是给定消息的原因,您只能看到某些Java版本的问题。