JAXB - unmarshalled fields are null

2019-02-22 06:11发布

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.

标签: java xml jaxb
3条回答
干净又极端
2楼-- · 2019-02-22 06:38

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.

查看更多
Animai°情兽
3楼-- · 2019-02-22 06:57

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


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);
查看更多
时光不老,我们不散
4楼-- · 2019-02-22 06:59

I solved this by making elementFormDefault="unqualified" in the xsd before generating stubs, else make the change manually in package-info.java

查看更多
登录 后发表回答