1

我有一个简单的 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.4axiom在 Java 7 中运行程序时,它工作正常。但是当我在 Java 8 中运行相同的东西时, S:role 和 S:mustunderstand 将更改为 env:role 和 env:mustunderstand (S 前缀更改为 env

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

我无法弄清楚这里的问题。这是否意味着woodstox 不支持Java 8 或者我错过了其他东西?

4

3 回答 3

2

PrefixSenv在您的文档中都映射到相同的命名空间 URI http://www.w3.org/2003/05/soap-envelope

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

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

于 2016-04-22T21:13:09.643 回答
1

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

所以:我猜这是由于 JDK 更改与字符串哈希码计算或 HashMap 条目的排序有关。鉴于有 2 个具有不同前缀的等效命名空间,当 Axiom 请求给定命名空间 URI 的前缀时,这两者的排序可能会导致不同的匹配;毕竟,两者都映射到相同的前缀,并且由于属性的顺序(其中命名空间前缀声明是特殊情况)在 XML 中是未定义的(也就是说,没有排序),任何一个都是有效的

如果没有 Woodstox 依赖项,处理可能会使用 JDK 嵌入的 Stax 解析器 (sjsxp),并且对其公开的排序可能会意外稳定,或者使用不基于哈希的机制。

于 2016-04-22T23:27:09.927 回答
0

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

Axiom 过去使用 aHashMap来存储命名空间声明;这可能就是为什么对于给定的消息,您只能看到某些 Java 版本的问题。

于 2016-05-02T17:06:30.803 回答