Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JAXB - unmarshalled fields are null

Tags:

java

xml

jaxb

We are unmarshalling a response from http://xmlgw.companieshouse.gov.uk/. This is the text sent to the marshall:

<NameSearch xmlns="http://xmlgw.companieshouse.gov.uk/v1-0/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlgw.companieshouse.gov.uk/v1-0/schema http://xmlgw.companieshouse.gov.uk/v1-0/schema/NameSearch.xsd">
  <ContinuationKey>...</ContinuationKey>
  <RegressionKey>...</RegressionKey>
  <SearchRows>20</SearchRows>
  <CoSearchItem>
    <CompanyName>COMPANY NAME</CompanyName>
    <CompanyNumber>23546457</CompanyNumber>
    <DataSet>LIVE</DataSet>
    <CompanyIndexStatus>DISSOLVED</CompanyIndexStatus>
    <CompanyDate></CompanyDate>
  </CoSearchItem>
  // more CoSearchItem elements
</NameSearch>

The model of CoSearchItem is like this:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "CoSearchItem", propOrder = {
    "companyName",
    "companyNumber",
    "dataSet",
    "companyIndexStatus",
    "companyDate",
    "searchMatch"
})
public class CoSearchItem {

    @XmlElement(name = "CompanyName", required = true)
    protected String companyName;
    @XmlElement(name = "CompanyNumber", required = true)
    protected String companyNumber;
    @XmlElement(name = "DataSet", required = true)
    protected String dataSet;
    @XmlElement(name = "CompanyIndexStatus")
    protected String companyIndexStatus;
    @XmlElement(name = "CompanyDate")
    @XmlSchemaType(name = "date")
    protected XMLGregorianCalendar companyDate;
    @XmlElement(name = "SearchMatch")
    protected String searchMatch;

    // getters and setters

}

NameSearch model has this structure:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "NameSearch", namespace = "http://xmlgw.companieshouse.gov.uk/v1-0/schema", propOrder = {
    "continuationKey",
    "regressionKey",
    "searchRows",
    "coSearchItem"
})
@XmlRootElement(name = "NameSearch", namespace = "http://xmlgw.companieshouse.gov.uk/v1-0/schema")
public class NameSearch {

    @XmlElement(name = "ContinuationKey", required = true)
    protected String continuationKey;
    @XmlElement(name = "RegressionKey", required = true)
    protected String regressionKey;
    @XmlElement(name = "SearchRows", required = true)
    protected BigInteger searchRows;
    @XmlElement(name = "CoSearchItem")
    protected List<CoSearchItem> coSearchItem;

    // setters and getters

}

The package has this annotations:

@XmlSchema(namespace = "http://xmlgw.companieshouse.gov.uk/v1-0", elementFormDefault = XmlNsForm.QUALIFIED, //
    xmlns = {
        @XmlNs(prefix = "xsi", namespaceURI = "http://www.w3.org/2001/XMLSchema-instance") 
     }
)

package uk.gov.companieshouse;

The unmarshaling is done from the first Node extracted from a larger Document, inside an any list of items. When we parse the xml however all the fields in CoSearchItem are set to null and can't figure out the reason.

like image 224
pablisco Avatar asked Feb 26 '13 09:02

pablisco


People also ask

Why does JAXB Unmarshaller return null?

The JAXB unmarshaller (the call to jaxbUnmarshaller.unmarshal(file);) does not return null - it returns an instance of Save, as it should. unmarshal() itself never returns null (see API docs of Unmarshaller: "An unmarshal method never returns null.") - however the fields in the instance it returns may be null.

How to Marshall and unmarshall JAXB XML in Java?

Create a new Class “ JAXBXMLHandler.java ” in the package “ com.theopentutorials.jaxb.xml ” and copy the following code. This is a helper class which has methods to perform marshalling and unmarshalling. These methods are called from client code (in this case, main () method).

What properties are supported by JAXB Unmarshaller?

JAXB Unmarshaller Properties. There currently are not any properties required to be supported by all JAXB Providers on Unmarshaller. However, some providers may support their own set of provider specific properties.

How to create JAXB book object in Java?

Create a new Class “ JAXBDemo.java ” in the package “ com.theopentutorials.jaxb.main ” and copy the following code. This class creates two book objects and stores it in list and calls marshal method from JAXBXMLHandler helper class passing list of objects and the file to write the object.


2 Answers

You need to use a package level @XmlSchema annotation to specify the namespace qualification for your model.

@XmlSchema(
    namespace = "http://xmlgw.companieshouse.gov.uk/v1-0/schema",
    elementFormDefault = XmlNsForm.QUALIFIED)
package example;

import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;

This this specified you do not require to specify the namespace URI on the @XmlRootElement and @XmlType on your NameSearch class.

For More Information

  • http://blog.bdoughan.com/2010/08/jaxb-namespaces.html

The unmarshaling is done from the first Node extracted from a larger Document, inside an any list of items.

Make sure the DOM parer used to create the nodes is namespace aware.

documentBuilderFactory.setNamespaceAware(true);
like image 58
bdoughan Avatar answered Oct 13 '22 12:10

bdoughan


I figured out the correct answer thanks to @Blaise Doughan. After looking at the package namespace qualification I found that it was pointing to:

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

and it should have been pointing to:

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

Not sure how that got misplaced.

like image 44
pablisco Avatar answered Oct 13 '22 14:10

pablisco