Неверное пространство имен при чтении XML в ответе Soap (не пусто) - PullRequest
0 голосов
/ 04 февраля 2019

У меня проблема с сервисом SOAP, который возвращает документы XML, непосредственно встроенные в SOAP 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> я сгенерировал классы Java с xjc из предоставленного XSD-файла.Для реализации веб-сервиса я использую javax.jws/javax.jws-api/1.1, javax.xml.ws/jaxws-api/2.3.1 и com.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: Как игнорировать пространство имен во время демаршаллинга XML-документа?

Есть ли другой способ получить Узел с правильным пространством имен?

1 Ответ

0 голосов
/ 04 февраля 2019

Вдохновлен JAXB: Как игнорировать пространство имен во время демаршаллинга XML-документа? Я реализовал решение, которое не является лучшим способом, поскольку необходимо сериализовать 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);
...