Unmarshal XML, где мыльный конверт является дочерним элементом, используя JAXB - PullRequest
0 голосов
/ 27 ноября 2018

Я хочу десериализовать следующий XML с помощью JAXB:

<testData>
    <tx>
        <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                      xmlns:ns="http://my/namespace">
            <soapenv:Header>
               ...
            </soapenv:Header>
            <soapenv:Body>
                ...
            </soapenv:Body>
        </soapenv:Envelope>
   </tx>

   <flag>true</flag>
   <someObject>
      ...
   </someObject>
</testData>

Проблема в том, что я не знаю, как представить мыльный конверт в модели Java, чтобы успешно десериализовать его.Это входные данные инструмента, созданного для наших тестеров, и конверт будет скопирован из SOAP UI.

Единственное решение, которое я придумал, - это использовать @XmlAnyElement(lax = true) и использовать конверт в качестве объекта вмодель, которая в конечном итоге будет десериализована до ElementNSImpl.Но это не выглядит лучшим решением.

Как я могу решить эту проблему?Также приветствуются предложения по изменению формата, поскольку они позволяют удобно хранить (в одном файле) и десериализовать скопированный мыльный конверт и дополнительные объекты, которые я добавил в примере XML.

Это мой Javaмодель на данный момент:

@XmlRootElement(name = "testData")
public class XMLWrapper {

    @XmlAnyElement(lax = true)
    private Object tx;
    private boolean flag;
    private SomeObject SomeObject;
}

и необратимая:

JAXBContext jaxbContext = JAXBContext.newInstance(XMLWrapper.class);
jaxbContext.createUnmarshaller().unmarshal(new File("file.xml"));

1 Ответ

0 голосов
/ 28 ноября 2018

Поскольку вы объявили для элемента XML <tx> свойство типа Object, у JAXB не было достаточно информации, чтобы создать что-то более конкретное, чем ElementNSImpl.

. Вам потребуется более совершенная модель Java.для элемента <tx>.Вместо того, чтобы объявлять его как тип Object

@XmlAnyElement(lax = true)
private Object tx;

, вам нужно объявить его с помощью полнофункционального Java-класса (назовем его Tx):

private Tx tx;

КлассTx представляет элемент XML <tx> и все, что вложено внутрь.Это может выглядеть так:

@XmlAccessorType(XmlAccessType.FIELD)
public class Tx {

    @XmlElement(name = "Envelope", namespace = "http://schemas.xmlsoap.org/soap/envelope/")
    private SoapEnvelope envelope;
}

Для моделирования элемента XML <soapenv:Envelope ...> вы объявляете свойство (назовем его SoapEnvelope envelope).Это свойство необходимо аннотировать @XmlElement, чтобы сообщить JAXB, что оно сопоставляется с именем элемента XML Envelope.Особенно обратите внимание на его параметр namespace, который соответствует определению пространства имен XML xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/".

Затем повторите ту же процедуру с классом SoapEnvelope для моделирования содержимого элемента XML <soapenv:Envelope>:

@XmlAccessorType(XmlAccessType.FIELD)
public class SoapEnvelope {

    @XmlElement(name = "Header", namespace = "http://schemas.xmlsoap.org/soap/envelope/")
    private SoapHeader header;

    @XmlElement(name = "Body", namespace = "http://schemas.xmlsoap.org/soap/envelope/")
    private SoapBody body;
}

Затем повторите ту же процедуру с классами SoapHeader и SoapBody для моделирования содержимого элементов XML <soapenv:Header> и <soapenv:Body>:

@XmlAccessorType(XmlAccessType.FIELD)
public class SoapHeader {
    ...
}
@XmlAccessorType(XmlAccessType.FIELD)
public class SoapBody {
    ...
}
...