简体   繁体   中英

unmarshal xml to object for a nested tag

I've got some generated classes from a 3rd party provider for their API - specifically Companies House ( http://xmlgw.companieshouse.gov.uk/ )

I'm having trouble unmarshalling the parts of the response from the API. I can cast the object to a GovTalkMessage object, which contains a Body tag - but the underlying object I get back after unsmarshalling is a ElementNSImpl object instead of the expected pojo.

Example

I create a request like this one: http://xmlgw.companieshouse.gov.uk/examples/companydetails_req.xml

And get a response like this one: http://xmlgw.companieshouse.gov.uk/examples/companydetails_reply.xml

You can see in the reply that there is:

<Body>
<CompanyDetails xmlns="http://xmlgw.companieshouse.gov.uk/v1-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlgw.companieshouse.gov.uk/v1-0/schema/CompanyDetails-v2-1.xsd">
    ...
</Body>

So the contents of the Body (which is a List<Object> in the generated GovTalkMessage pojo) should have a CompanyDetails object in the first element of the list. I instead have ElementNSImpl .

Here's the marshalling code, which works fine - can send it to the API endpoint and comes back with an xml response like the example above:

JAXBContext context = JAXBContext.newInstance(GovTalkMessage.class, CompanyDetailsRequest.class, CompanyDetails.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

InputStream in = Request.Post ... //omitted - send to server, get response

Unmarshaller unmarshaller = context.createUnmarshaller();
GovTalkMessage reply = (GovTalkMessage)unmarshaller.unmarshal(in); //ok
Object object = reply.getBody().getAny().get(0); 
//object is ElementNSImpl - should be CompanyDetails

Am I doing something wrong in the unmarshal?

Thanks in advance

UPDATE

If I modify the package-info.java to have

namespace = "http://xmlgw.companieshouse.gov.uk/v1-0/schema"

instead of

namespace = "http://www.govtalk.gov.uk/CM/envelope"

then the unmarshal works. But I can't get both marshal into GovTalkMessage and unmarshal into CompanyAppointments to work, even if I specify it directy:

JAXBContext payloadContext = JAXBContext.newInstance(CompanyAppointments.class);
Unmarshaller unmarshaller = payloadContext.createUnmarshaller();
unmarshaller.unmarshal((Node)message.getBody().getAny().get(0), CompanyAppointments.class).getValue();

This just gives me a CompanyAppointments with fields full of nulls.

It seems namespace used for generating binding classes and one received in response are conflicted.

binding class and XML response will be required to point out error here :).

I'll suggest you to use package name in place of classes for creating JAXBContext.

final JAXBContext context = JAXBContext.newInstance("com.something"...);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM