Generating java classes from xsd files
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.javabb/commonElement.java
bb/b.javaThis 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 nam开发者_运维技巧espace="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.javaThe 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
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);
}
}
I have one question if know then please explain. I have tried above answer and its working fine with given details.
But suppose I want to below xml validation It will same as you have given, But I did some little change that I want to validate
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Response xmlns="http://www.ns.com/aa">
<element xmlns="http://www.ns.com/common">
<commonChild>FOO</commonChild>
</element>
</Response>
But It will give below error
SAX Exception: cvc-complex-type.2.4.a: Invalid content was found starting with element 'element'. One of '{"http://www.ns.com/aa":element}' is expected.
is not valid against
精彩评论