代码之家  ›  专栏  ›  技术社区  ›  Madjosz

在Soap响应中读取XML时命名空间错误(非空)

  •  0
  • Madjosz  · 技术社区  · 5 年前

    我有一个SOAP服务的问题,它返回直接嵌入soapxml中的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 从提供的XSD文件。对于我正在使用的webservice实现 javax.jws/javax.jws-api/1.1 , javax.xml.ws/jaxws-api/2.3.1 com.sun.xml.ws/rt/2.3.1 . 表示 <实际mldocument> 我从我的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生成的文件。另外,我不能控制webservice的服务器端,所以我不能改变它的行为。我现在看到的唯一可能是 JAXB: How to ignore namespace during unmarshalling XML document?

    是否有其他方法可以获得具有正确名称空间的节点?

    1 回复  |  直到 5 年前
        1
  •  1
  •   Madjosz    5 年前

    灵感来自 JAXB: How to ignore namespace during unmarshalling XML document?

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