【问题标题】:Wrong namespace when reading XML in Soap response (not empty)在 Soap 响应中读取 XML 时命名空间错误(非空)
【发布时间】:2019-02-04 12:08:41
【问题描述】:

我有一个 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>

&lt;Result&gt;根据WSDL的内容类型是

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

对于&lt;ActualXmlDocument&gt;,我从提供的XSD 文件中生成了带有xjc 的Java 类。对于网络服务实现,我使用javax.jws/javax.jws-api/1.1javax.xml.ws/jaxws-api/2.3.1com.sun.xml.ws/rt/2.3.1。我从 WS 实现中检索到的表示 &lt;ActualXmlDocument&gt; 的对象的类型是 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 生成的文件。此外,我无法控制 Web 服务的服务器端,因此无法更改其行为。我现在看到的唯一可能是JAXB: How to ignore namespace during unmarshalling XML document?

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

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

【问题讨论】:

    标签: java xml soap jaxb xml-namespaces


    【解决方案1】:

    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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-05
      • 1970-01-01
      • 2014-06-20
      • 1970-01-01
      • 2017-06-10
      • 2011-03-30
      相关资源
      最近更新 更多