我有它返回直接嵌入在SOAP XML XML文档的SOAP服务的问题。 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>
我已生成的Java类与所提供的XSD文件xjc
。对于Web服务的实现,我使用javax.jws/javax.jws-api/1.1
,javax.xml.ws/jaxws-api/2.3.1
和com.sun.xml.ws/rt/2.3.1
。代表我从WS实现检索<ActualXmlDocument>
的对象的类型是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?
有一些其他的方式来获得与正确的命名空间节点?
通过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);