java - 在 Soap 响应中读取 XML 时出现错误的命名空间(非空)

标签 java xml soap jaxb xml-namespaces

我在使用 SOAP 服务时遇到问题,该服务返回直接嵌入 SOAP XML 中的 XML 文档。 SOAP 响应如下所示:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Header />
    <soap:Body xmlns="WebserviceNamespace">
        <Result xmlns="WebserviceNamespace">
            <ActualXmlDocument DtdRelease="0" DtdVersion="4" xmlns="">
                ...
            </ActualXmlDocument>
        </Result>
    </soap:Body>
</soap:Envelope>

<Result> 的内容类型根据 WSDL 是

<s:element minOccurs="0" maxOccurs="1" name="Result">
    <s:complexType mixed="true">
        <s:sequence>
            <s:any />
        </s:sequence>
    </s:complexType>
</s:element>

对于<ActualXmlDocument>我已经用 xjc 生成了 Java 类来自提供的 XSD 文件。对于网络服务实现,我使用 javax.jws/javax.jws-api/1.1 , javax.xml.ws/jaxws-api/2.3.1com.sun.xml.ws/rt/2.3.1 。代表 <ActualXmlDocument> 的对象类型我从我的 WS 实现中检索的是 com.sun.org.apache.xerces.internal.dom.ElementNSImpl它实现了 org.w3c.dom.Node 。尝试使用 JAXB 解码时

JAXBContext context = JAXBContext.newInstance(ActualXmlDocument.class);
context.createUnmarshaller().unmarshal((Node)result);

我收到以下异常

UnmarshalException:
    unexpected element (URI:"WebserviceNamespace", local:"ActualXmlDocument").
    Expected elements are <{}ActualXmlDocument>

因此,由于某些原因,在读取 XML 文档时,空命名空间不会被视为新的默认命名空间,而是会被错位的 WebseriveNamespace 覆盖。

那么我该如何解决这个问题呢?我不想仅仅为了适应这种明显错误的行为而修改 XSD 生成的文件。另外,我无法控制网络服务的服务器端,因此我无法更改其行为。我现在看到的唯一可能性是 JAXB: How to ignore namespace during unmarshalling XML document?

还有其他方法可以获取具有正确命名空间的节点吗?

编辑:这实际上是com.sun.xml.ws.api.message.saaj.SaajStaxWriter中的一个错误。 ,在 JDK 1.8.0u172 中解决但不幸的是 JAX WS 本身没有。

最佳答案

灵感来自JAXB: How to ignore namespace during unmarshalling XML document?我实现了一个解决方案,但这不是最好的方法,因为它需要将 DOM 序列化为 XML 文档:

JAXBContext context = JAXBContext.newInstance(ActualXmlDocument.class);
Unmarshaller unmarshaller = context.createUnmarshaller();

SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
saxParserFactory.setNamespaceAware(false);
XMLReader xmlReader = saxParserFactory.newSAXParser().getXMLReader();

Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "no");
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
OutputStreamout = new ByteArrayOutputStream();
StreamResult streamResult = new StreamResult(out);
transformer.transform(new DOMSource(result), streamResult);

InputStream in = new ByteArrayInputStream(out.toByteArray())
SAXSource source = new SAXSource(xmlReader, new InputSource(in));

unmarshaller.unmarshal(source);

关于java - 在 Soap 响应中读取 XML 时出现错误的命名空间(非空),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54515781/

相关文章:

java - 模拟@AuthenticationPrincipal进行单元测试

具有短日期模式的 java 本地化日期

php - 使用 xpath 选择 css 类

c# - 写入现有的 XML 文件

javascript - 将 XForm 实例序列化为 SOAPAttach 附件

java - Spring JPA CrudRepository Autowired 对象与 Apache Commons Tailer 一起使用时为 null

java - 通过单击按钮创建变量

java - Salesforce:在 Salesforce 中为某些配置文件创建用户时收到 "PORTAL_NO_ACCESS"错误消息

python - 如何使用 python (suds) 对 XML 进行签名

java - 如何使用 Jackson 获取特定时区的日历?