Question

I have got a xsd files from some thirdparty which used to be with "include" and not "import". I am using these xsd file to generate java files, using jaxb. The initial xsd structure resulted in output in which same classe were included in different packages. for example, if two packages were generated, "aa" and "bb", both included the same common file :

aa/commonElement.java
aa/a.java

bb/commonElement.java
bb/b.java

This was something I wanted to avoid, I wanted commonElement.java to be created once in single package and than imported by the rest, thus I have started to use import instead.

<xs:schema xmlns="http://www.ns.com/aa" xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:DD="http://www.ns.com/common" targetNamespace="http://www.ns.com/aa" elementFormDefault="qualified" jaxb:version="1.0" jaxb:extensionBindingPrefixes="xjc">

 <xs:import namespace="http://www.ns.com/common"  schemaLocation="common.xsd"/>
   <xs:element name="Response">
                <xs:complexType>
                        <xs:sequence>
                                    <xs:element name="element" type="DD:commonElement" ../>

The java classes were created and compiled and as I expected.

common/commonElement.java
aa/aa.java

The problem is when I receive a result of aa, from an api call and unmarshal the results, I get aa class with commonElement created correctly, but with empty fields.

My guess is that the fields are empty because the unmarshler does not understand that he need to look for the definition in "common" namespace and instead is looking for them in "aa" namesapce but how to make it work correctly?

Thanks for the help

Was it helpful?

Solution

I don't have enough information to diagnose why your unmarshal is not happening correctly. The following will work, you might be able to compare it to what you are doing to find the error.

The most likely candidates are:

  • You are not telling JAXB about enough classes when you create the JAXBContext.
  • Your XML document is not properly namespace qualified.

Using the following schemas:

common.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="http://www.ns.com/common" 
    xmlns="http://www.ns.com/common" 
    elementFormDefault="qualified">

    <xs:complexType name="commonElement">
        <xs:sequence>
            <xs:element name="commonChild" type="xs:string"/>
        </xs:sequence>
    </xs:complexType>
</xs:schema>

aa.xsd

<xs:schema xmlns="http://www.ns.com/aa" xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:DD="http://www.ns.com/common" targetNamespace="http://www.ns.com/aa"
    elementFormDefault="qualified">

    <xs:import namespace="http://www.ns.com/common"
        schemaLocation="common.xsd" />

    <xs:element name="Response">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="element" type="DD:commonElement" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

The following classes were generated:

com.ns.aa.package-info

@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.ns.com/aa", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.ns.aa;

com.ns.aa.Response

package com.ns.aa;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import com.ns.common.CommonElement;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "element"
})
@XmlRootElement(name = "Response")
public class Response {

    @XmlElement(required = true)
    protected CommonElement element;

    public CommonElement getElement() {
        return element;
    }

    public void setElement(CommonElement value) {
        this.element = value;
    }

}

com.ns.common.package-info

@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.ns.com/common", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.ns.common;

com.ns.common.CommonElement

package com.ns.common;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "commonElement", propOrder = {
    "commonChild"
})
public class CommonElement {

    @XmlElement(required = true)
    protected String commonChild;

    public String getCommonChild() {
        return commonChild;
    }

    public void setCommonChild(String value) {
        this.commonChild = value;
    }

}

With these classes I can unmarshal the following XML document:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:Response xmlns="http://www.ns.com/common" xmlns:ns2="http://www.ns.com/aa">
    <ns2:element>
        <commonChild>FOO</commonChild>
    </ns2:element>
</ns2:Response>

Using the following code:

Demo

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import com.ns.aa.Response;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Response.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("input.xml");
        Response response = (Response) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(response, System.out);
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top