views:

101

answers:

1

Hi, 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

A: 

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"&gt;
    <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);
    }
}
Blaise Doughan
You are correct.The problem is that I do not receive the xml with the correct attributes, like in your example <ns2:element>, to reflect the schema change I did. And when I manually edited the xml the object was unmarshalled correctly.The thing is that if I can not control the xml structure, since I receive it from some other party. So the question is : Can I make some change on my side so the unmarshling will successfully find the elements anyway ?Thanks
anyab
Can you provide a sample document? The answer depends on whether "element" is in the default namespace or no namespace.
Blaise Doughan