Create XSD for class structure - xsd

I would like to describe this class structure by XSD but I couldnt find any solution:
public class A {
string property { get; }
B[] property2 { get; }//occurs 0 to unbound
}
public class B {
string property { get; }
}

Here's what i think, the following XML schema will help you solve your problem.
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/Class" xmlns:tns="http://www.example.org/Class" elementFormDefault="qualified">
<element name="A" type="tns:A"></element>
<simpleType name="property">
<restriction base="string"></restriction>
</simpleType>
<complexType name="B">
<sequence>
<element name="property" type="tns:property"></element>
</sequence>
</complexType>
<complexType name="A">
<sequence>
<element name="property" type="tns:property"></element>
<element name="B" type="tns:B" maxOccurs="unbounded" minOccurs="0"></element>
</sequence>
</complexType>

If you are using C# take a look at this question/answer :
Programatically serialize class to xsd
But the problem when serializing to XSD is that DataMember attributes have serious limitations for XSD (see http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/e95ba78b-9932-4d8a-91ac-6b40967d0d8b).
So, maybe you can generate your XSD by serialization and perform some custom modifications, essentially for data constraints (length, ranges, min/max...)
[Edit] Or if you want to do it by yourself take a look at this http://www.w3schools.com/schema/

Related

Apache CXF Generated JAXB class has #XMLElement with Blank/Empty "" Namespace for External Schema/XSD

I am using Apache CXF maven cxf-codegen-plugin (wsdl2java) to generate JAXB classes from wsdl which includes external XSD and uses the complex type in XSD to define element.
pom.xml Snippet -
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>3.4.1</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<wsdlOption>
<wsdl>${base.wsdl.path}/myWSDL.wsdl</wsdl>
<extraargs>
<extraarg>-p</extraarg>
<extraarg>${base.package.name}.mywsdl</extraarg>
</extraargs>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
myWSDL.wsdl Snippet-
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="myService"
targetNamespace="http://com.company/myservice/schemas">
<wsdl:types>
<xs:schema xmlns="http://com.company/myservice/schemas"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://com.company/myservice/schemas">
<xsd:include schemaLocation="myXSD.xsd"/>
<xsd:complexType name="myElementType">
<xsd:sequence>
<xsd:element name="MyElementXSD" type="MyElementComplexTypeFromXSD" minOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xs:element name="MyElement" type="myElementType"/>
...
...
</xs:schema>
</wsdl:types>
myXSD.xsd -
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://com.company/myservice/schemas" targetNamespace="http://com.company/myservice/schemas">
<complexType name="MyElementComplexTypeFromXSD">
<attribute name="MyAttribute" type="string"/>
</complexType>
</schema>
Generated MyElement.java -
public class MyElement {
#XmlElement(name = "MyElementXSD", namespace="", required = true)
protected MyElementXSD myElementXSD;
}
With these WSDL and XSD, generated JAXB class has explicitly empty namespace which is causing issue during unmarshalling.
If I modify WSDL and XSD as below, generated JAXB class is proper and unmarshalling works just fine.
Create element of complex type directly in XSD -
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://com.company/myservice/schemas" targetNamespace="http://com.company/myservice/schemas">
<element name="MyElementXSD">
<complexType >
<attribute name="MyAttribute" type="string"/>
</complexType>
</element>
</schema>
Refer to it directly using 'ref' instead of 'type' in WSDL -
<xsd:complexType name="myElementType">
<xsd:sequence>
<xsd:element ref="MyElementXSD" minOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
Then generated class #XmlElement changes to -
public class MyElement {
#XmlElement(name = "MyElementXSD", required = true)
protected MyElementXSD myElementXSD;
}
But I am not at liberty to touch provided WSDLs and XSDs, hence looking for solutions/suggestions such as passing some argument to CXF maven plugin/using a binding file etc.

JAXB schema to Java Different XmlRootElement name and Class name

I have a xsd schema from which I'm generating some java classes. I'm using jaxb for the generation.
I want to be able to generate a class annotated with #XmlRootElement, but I want the #XmlRootElement name property to be different than the name of the generated class.
In my xsd I'm defining the following:
<xs:element name="customer">
<xs:complexType>
<xs:sequence>
....
</xs:sequence>
</xs:complexType>
</xs:element>
This piece of code generates the following java class:
#XmlRootElement(name = "customer")
public class Customer {
...
}
The name property of the #XmlRootElement is the same as the name of the generated Class. I want the generated class name to be CustomerRequest.
I've tryed to use the jaxb:class definition to change the classe name. Indeed this option changes the class name but removes the #XmlRootElement annotation, and I need it to be present.
The following xsd:
<xs:element name="customer">
<xs:complexType>
<xs:annotation>
<xs:appinfo>
<jaxb:class name="CustomerRequest"/>
</xs:appinfo>
</xs:annotation>
<xs:sequence>
</xs:sequence>
</xs:complexType>
</xs:element>
Generates this class:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "customer", propOrder = {
})
public class CustomerRequest {
}
How can I make the property name of the #XmlRootElement annotation different from the generated class name without loosing the annotation?
Solution update:
User Xstian proposed the correct solution using external bindings.
Just for further reference, I'll update my own post with the solution converted for using inline bindings:
<xs:element name="customer">
<xs:complexType>
<xs:annotation>
<xs:documentation>Request object for the operation that checks if a customer profile exists.</xs:documentation>
<xs:appinfo>
<annox:annotate>
<annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement" name="customer"/>
</annox:annotate>
<jaxb:class name="CustomerRequest"/>
</xs:appinfo>
</xs:annotation>
<xs:sequence>
</xs:sequece>
</xs:complexType>
</xs:element>
I suggest you to use this bindings
<bindings version="2.0" xmlns="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:annox="http://annox.dev.java.net"
xmlns:namespace="http://jaxb2-commons.dev.java.net/namespace-prefix">
<bindings schemaLocation="../your.xsd">
<bindings node="//xs:element[#name='customer']//xs:complexType">
<annox:annotate>
<annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement"
name="customer" namespace="yourNamespaceIfYouWant">
</annox:annotate>
</annox:annotate>
<class name="CustomerRequest"/>
</bindings>
</bindings>
</bindings>
Class
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"header"
})
#XmlRootElement(name = "customer", namespace = "yourNamespaceIfYouWant")
public class CustomerRequest

error trying to marshal a JAXB root object missing #XmlRootElement

I have a complex xml schema that is part of an international standard, therefore I can't change the schema files, and I have used Maven to generate JAXB objects from them. When I try to set data into my JAXB objects and then marshal the root element I get the missing #XmlRootElement error on several of the complex types. My question is how do I resolve this?
Environment:
JAXB 2.2.2
Maven 3.0.3
Eclipse Juno
Java 1.6
Windows 7 64 bit
I have researched the web and this site extensively but have not found an answer to my problem, including this post:
http://weblogs.java.net/blog/kohsuke/archive/2006/03/why_does_jaxb_p.html
and this question on stack overflow:
JAX-WS MarshalException with custom JAX-B bindings: Unable to marshal type "java.lang.String" as an element because it is missing an #XmlRootElement annotation
I have tried adding an annotation to the offending classes in my custom binding file, but it adds the annotation to the class as well as the getContent() method and the class won't compile. I don't think I should have to add this annotation anyway, since this is a complex type that is a component of the root, actually it's nested fairly deep in the tree. I have read that you can add the <xjc:simple/> tag to the global binding element, but I have added a number of attributes to the global binding element and it won't compile when I do that.
Can someone help point me in the right direction here, could this be an error in the way I am building up the JAXB objects? I have walked it through in the debugger and it seems that when the ArrayReferenceNodeProperty class from the package com.sun.xml.bind.v2.runtime.property tries to serialize the list body and when it gets the JaxBeanInfo for these classes there isn't a dom handler set and the jaxbType is not an object so it thinks it needs to be a root.
I am not using this in a web based service and other than the tweaks in the binding file to resolve naming conflicts have not created any custom classes or bindings.
Here is the top level schema file:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="qualified">
<xs:annotation>
<xs:documentation>
*****************************************************************************
* *
* S1000D Issue 3 *
* XML Schema *
* *
* Release Version 3.0 *
* Date: 2007-07-31 *
* *
* *
* The following attribute definition on the root element may be used to *
* call this set of declarations:- *
* *
* xsi:noNamespaceSchemaLocation= *
* "http://www.s1000d.org/S1000D_3-0/xml_schema_master/dm/procedSchema.xsd" *
*****************************************************************************
</xs:documentation>
</xs:annotation>
<xs:redefine schemaLocation="elementGroups.xsd">
<xs:group name="APPLIC">
<xs:choice>
<xs:sequence>
<xs:element ref="displaytext"/>
<xs:choice minOccurs="0">
<xs:element ref="assert"/>
<xs:element ref="evaluate"/>
</xs:choice>
</xs:sequence>
<xs:choice>
<xs:element ref="assert"/>
<xs:element ref="evaluate"/>
</xs:choice>
</xs:choice>
</xs:group>
<xs:group name="NPAR">
<xs:sequence>
<xs:group ref="WC"/>
<xs:group ref="NPFFT" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:group>
<xs:group name="NPFFT">
<xs:choice>
<xs:group ref="NP"/>
<xs:group ref="FFT"/>
</xs:choice>
</xs:group>
<xs:group name="paracon">
<xs:choice>
<xs:group ref="text"/>
<xs:group ref="list"/>
</xs:choice>
</xs:group>
<xs:group name="text">
<xs:choice>
<xs:element ref="ein"/>
<xs:element ref="cb"/>
<xs:element ref="parasigdata"/>
<xs:element ref="quantity"/>
<xs:element ref="xref"/>
<xs:element ref="indxflag"/>
<xs:element ref="change"/>
<xs:element ref="emphasis"/>
<xs:element ref="symbol"/>
<xs:element ref="subscrpt"/>
<xs:element ref="supscrpt"/>
<xs:element ref="refdm"/>
<xs:element ref="reftp"/>
<xs:element ref="ftnote"/>
<xs:element ref="ftnref"/>
<xs:element ref="acronym"/>
<xs:element ref="acroterm"/>
<xs:element ref="capgrp"/>
</xs:choice>
</xs:group>
<xs:group name="TEXT-NOREFS">
<xs:choice>
<xs:element ref="xref"/>
<xs:element ref="indxflag"/>
<xs:element ref="symbol"/>
<xs:element ref="subscrpt"/>
<xs:element ref="supscrpt"/>
<xs:element ref="ftnref"/>
<xs:element ref="acronym"/>
<xs:element ref="acroterm"/>
</xs:choice>
</xs:group>
<xs:group name="STEP1">
<xs:sequence>
<xs:element ref="step1"/>
</xs:sequence>
</xs:group>
<xs:group name="STEP2">
<xs:sequence>
<xs:element ref="step2"/>
</xs:sequence>
</xs:group>
<xs:group name="STEP3">
<xs:sequence>
<xs:element ref="step3"/>
</xs:sequence>
</xs:group>
<xs:group name="STEP4">
<xs:sequence>
<xs:element ref="step4"/>
</xs:sequence>
</xs:group>
<xs:group name="STEP5">
<xs:sequence>
<xs:element ref="step5"/>
</xs:sequence>
</xs:group>
<xs:group name="STEP6">
<xs:sequence>
<xs:element ref="step6"/>
</xs:sequence>
</xs:group>
<xs:group name="STEP7">
<xs:sequence>
<xs:element ref="step7"/>
</xs:sequence>
</xs:group>
<xs:group name="STEP8">
<xs:sequence>
<xs:element ref="step8"/>
</xs:sequence>
</xs:group>
</xs:redefine>
<xs:redefine schemaLocation="complexTypes.xsd">
<xs:complexType name="contentType">
<xs:complexContent>
<xs:restriction base="contentType">
<xs:sequence>
<xs:element ref="refs" minOccurs="0"/>
<xs:element ref="proced"/>
</xs:sequence>
<xs:attribute ref="id"/>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
</xs:redefine>
<xs:element name="dmodule" type="dmoduleType"/>
For the xrefType I am only setting two attributes and for the refdmType I am only setting one other complex type that is part of the ALLDMC group. The code for the two complex types that error is:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" elementFormDefault="qualified" attributeFormDefault="qualified">
<xs:import namespace="http://www.w3.org/1999/02/22-rdf-syntax-ns#" schemaLocation="rdf.xsd"/>
<xs:import namespace="http://www.w3.org/1999/xlink" schemaLocation="xlink.xsd"/>
<xs:include schemaLocation="attributeGroups.xsd"/>
<xs:include schemaLocation="simpleElements.xsd"/>
<xs:include schemaLocation="complexElements.xsd"/>
<xs:include schemaLocation="elementGroups.xsd"/>
<xs:complexType name="refdmType">
<xs:choice>
<xs:sequence>
<xs:element ref="applic" minOccurs="0"/>
<xs:element ref="dmcextension" minOccurs="0"/>
<xs:group ref="ALLDMC"/>
<xs:element ref="issno" minOccurs="0"/>
<xs:element ref="dmtitle" minOccurs="0"/>
<xs:element ref="language" minOccurs="0"/>
</xs:sequence>
<xs:group ref="xlink:XLINKEXT" minOccurs="0" maxOccurs="unbounded"/>
</xs:choice>
<xs:attribute ref="target"/>
<xs:attribute ref="refapplic"/>
<xs:attributeGroup ref="bodyatt"/>
<xs:attributeGroup ref="cntlcontent"/>
<xs:attributeGroup ref="xlink:XLINKATT"/>
</xs:complexType>
<xs:complexType name="xrefType" mixed="true">
<xs:sequence>
<xs:element ref="applic" minOccurs="0"/>
<xs:group ref="SPARCON" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute ref="xrefid"/>
<xs:attribute ref="xidtype"/>
<xs:attribute ref="target"/>
<xs:attribute ref="destitle"/>
<xs:attribute ref="pretext"/>
<xs:attribute ref="posttext"/>
<xs:attribute ref="refapplic"/>
<xs:attributeGroup ref="cntlcontent"/>
<xs:attributeGroup ref="xlink:XLINKATT3"/>
</xs:complexType>
</xs:schema>
And here is the main part of the JAXB generated classes. I have removed most of the getters and setters to save space:
The RefdmType:
/**
* <p>Java class for refdmType complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType name="refdmType">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <choice>
* <sequence>
* <element ref="{}applic" minOccurs="0"/>
* <element ref="{}dmcextension" minOccurs="0"/>
* <group ref="{}ALLDMC"/>
* <element ref="{}issno" minOccurs="0"/>
* <element ref="{}dmtitle" minOccurs="0"/>
* <element ref="{}language" minOccurs="0"/>
* </sequence>
* <group ref="{http://www.w3.org/1999/xlink}XLINKEXT" maxOccurs="unbounded" minOccurs="0"/>
* </choice>
* <attGroup ref="{http://www.w3.org/1999/xlink}XLINKATT"/>
* <attGroup ref="{}cntlcontent"/>
* <attGroup ref="{}bodyatt"/>
* <attribute ref="{}target"/>
* <attribute ref="{}refapplic"/>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "refdmType", propOrder = {
"applicAndDmcextensionAndAge"
})
public class RefdmType implements Serializable
{
private final static long serialVersionUID = 1L;
#XmlElements({
#XmlElement(name = "applic", type = ApplicType.class),
#XmlElement(name = "dmcextension", type = DmcextensionType.class),
#XmlElement(name = "age", type = AgeType.class),
#XmlElement(name = "avee", type = AveeType.class),
#XmlElement(name = "issno", type = IssnoType.class),
#XmlElement(name = "dmtitle", type = DmtitleType.class),
#XmlElement(name = "language", type = LanguageType.class),
#XmlElement(name = "resource", namespace = "http://www.w3.org/1999/xlink", type = Resource.class),
#XmlElement(name = "locator", namespace = "http://www.w3.org/1999/xlink", type = Locator.class),
#XmlElement(name = "arc", namespace = "http://www.w3.org/1999/xlink", type = Arc.class)
})
protected List<Serializable> applicAndDmcextensionAndAge;
#XmlAttribute(name = "target")
protected String target;
#XmlAttribute(name = "refapplic")
#XmlIDREF
#XmlSchemaType(name = "IDREF")
protected Object refapplic;
#XmlAttribute(name = "type", namespace = "http://www.w3.org/1999/xlink")
#XmlJavaTypeAdapter(CollapsedStringAdapter.class)
protected String type;
#XmlAttribute(name = "href", namespace = "http://www.w3.org/1999/xlink")
protected String href;
#XmlAttribute(name = "title", namespace = "http://www.w3.org/1999/xlink")
protected String title;
#XmlAttribute(name = "show", namespace = "http://www.w3.org/1999/xlink")
#XmlJavaTypeAdapter(CollapsedStringAdapter.class)
protected String show;
#XmlAttribute(name = "actuate", namespace = "http://www.w3.org/1999/xlink")
#XmlJavaTypeAdapter(CollapsedStringAdapter.class)
protected String actuate;
#XmlAttribute(name = "authname")
protected String authname;
#XmlAttribute(name = "authdoc")
protected String authdoc;
#XmlAttribute(name = "id")
#XmlJavaTypeAdapter(CollapsedStringAdapter.class)
#XmlID
#XmlSchemaType(name = "ID")
protected String id;
#XmlAttribute(name = "level")
#XmlSchemaType(name = "nonNegativeInteger")
protected BigInteger level;
#XmlAttribute(name = "mark")
#XmlSchemaType(name = "nonNegativeInteger")
protected BigInteger mark;
#XmlAttribute(name = "change")
protected ChangeType change;
#XmlAttribute(name = "rfc")
protected String rfc;
/**
* Gets the value of the applicAndDmcextensionAndAge property.
*
* <p>
* This accessor method returns a reference to the live list,
* not a snapshot. Therefore any modification you make to the
* returned list will be present inside the JAXB object.
* This is why there is not a <CODE>set</CODE> method for the applicAndDmcextensionAndAge property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getApplicAndDmcextensionAndAge().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {#link ApplicType }
* {#link DmcextensionType }
* {#link AgeType }
* {#link AveeType }
* {#link IssnoType }
* {#link DmtitleType }
* {#link LanguageType }
* {#link Resource }
* {#link Locator }
* {#link Arc }
*
*
*/
public List<Serializable> getApplicAndDmcextensionAndAge() {
if (applicAndDmcextensionAndAge == null) {
applicAndDmcextensionAndAge = new ArrayList<Serializable>();
}
return this.applicAndDmcextensionAndAge;
}
}
The XrefType:
/**
* <p>Java class for xrefType complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType name="xrefType">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element ref="{}applic" minOccurs="0"/>
* <group ref="{}SPARCON" maxOccurs="unbounded" minOccurs="0"/>
* </sequence>
* <attGroup ref="{}cntlcontent"/>
* <attGroup ref="{http://www.w3.org/1999/xlink}XLINKATT3"/>
* <attribute ref="{}xrefid"/>
* <attribute ref="{}xidtype"/>
* <attribute ref="{}target"/>
* <attribute ref="{}destitle"/>
* <attribute ref="{}pretext"/>
* <attribute ref="{}posttext"/>
* <attribute ref="{}refapplic"/>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "xrefType", propOrder = {
"content"
})
public class XrefType implements Serializable
{
private final static long serialVersionUID = 1L;
#XmlElementRefs({
#XmlElementRef(name = "supscrpt", type = JAXBElement.class),
#XmlElementRef(name = "subscrpt", type = JAXBElement.class),
#XmlElementRef(name = "applic", type = JAXBElement.class)
})
#XmlMixed
protected List<Serializable> content;
#XmlAttribute(name = "xrefid")
#XmlJavaTypeAdapter(Adapter5 .class)
#XmlSchemaType(name = "IDREF")
protected String xrefid;
#XmlAttribute(name = "xidtype")
protected XidtypeType xidtype;
#XmlAttribute(name = "target")
protected String target;
#XmlAttribute(name = "destitle")
protected String destitle;
#XmlAttribute(name = "pretext")
protected String pretext;
#XmlAttribute(name = "posttext")
protected String posttext;
#XmlAttribute(name = "refapplic")
#XmlIDREF
#XmlSchemaType(name = "IDREF")
protected Object refapplic;
#XmlAttribute(name = "authname")
protected String authname;
#XmlAttribute(name = "authdoc")
protected String authdoc;
#XmlAttribute(name = "type", namespace = "http://www.w3.org/1999/xlink")
#XmlJavaTypeAdapter(CollapsedStringAdapter.class)
protected String type;
#XmlAttribute(name = "href", namespace = "http://www.w3.org/1999/xlink")
protected String href;
#XmlAttribute(name = "title", namespace = "http://www.w3.org/1999/xlink")
protected String title;
#XmlAttribute(name = "show", namespace = "http://www.w3.org/1999/xlink")
#XmlJavaTypeAdapter(CollapsedStringAdapter.class)
protected String show;
#XmlAttribute(name = "actuate", namespace = "http://www.w3.org/1999/xlink")
#XmlJavaTypeAdapter(CollapsedStringAdapter.class)
protected String actuate;
/**
* Gets the value of the content property.
* <p>
* This accessor method returns a reference to the live list,
* not a snapshot. Therefore any modification you make to the
* returned list will be present inside the JAXB object.
* This is why there is not a <CODE>set</CODE> method for the content property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getContent().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {#link String }
* {#link JAXBElement }{#code <}{#link String }{#code >}
* {#link JAXBElement }{#code <}{#link ApplicType }{#code >}
* {#link JAXBElement }{#code <}{#link String }{#code >}
*
*
*/
public List<Serializable> getContent() {
if (content == null) {
content = new ArrayList<Serializable>();
}
return this.content;
}
}
And finally here is my custom binding file:
<jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:annox="http://annox.dev.java.net"
xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd">
<jxb:globalBindings typesafeEnumMemberName="generateName"
typesafeEnumMaxMembers="1500" collectionType="java.util.ArrayList"
generateValueClass="true" choiceContentProperty="true">
<xjc:serializable uid="1" />
</jxb:globalBindings>
<jxb:bindings schemaLocation="simpleTypes.xsd" node="/xs:schema">
<jxb:bindings node="//xs:simpleType[#name='YEAR']">
<jxb:javaType name="java.lang.Integer" />
</jxb:bindings>
<jxb:bindings node="//xs:simpleType[#name='DAY']">
<jxb:javaType name="java.lang.String" />
</jxb:bindings>
<jxb:bindings node="//xs:simpleType[#name='MONTH']">
<jxb:javaType name="java.lang.String" />
</jxb:bindings>
<jxb:bindings node="//xs:simpleType[#name='issnovalueType']">
<jxb:javaType name="java.lang.String" />
</jxb:bindings>
</jxb:bindings>
<jxb:bindings schemaLocation="attributes.xsd" node="/xs:schema">
<jxb:bindings node="xs:attribute[#name='inwork']">
<jxb:property>
<jxb:baseType>
<jxb:javaType name="java.lang.String" />
</jxb:baseType>
</jxb:property>
</jxb:bindings>
<jxb:bindings node="//xs:attribute[#name='xrefid']">
<jxb:property>
<jxb:baseType>
<jxb:javaType name="java.lang.String" />
</jxb:baseType>
</jxb:property>
</jxb:bindings>
</jxb:bindings>
<jxb:bindings schemaLocation="complexTypes.xsd" node="/xs:schema">
<jxb:bindings node="xs:complexType[#name='dmoduleType']">
<annox:annotate>
<annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement"
name="dmodule" />
</annox:annotate>
</jxb:bindings>
<jxb:bindings node="//xs:complexType[#name='skillType']">
<jxb:class name="SkillTypeComplex" />
</jxb:bindings>
<!--<jxb:bindings node="//xs:complexType[#name='xrefType']">
<annox:annotate>
<annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement"
name="xref" />
</annox:annotate>
<jxb:bindings node=".//xs:sequence//xs:element[#ref='applic']">
<jxb:property name="xrefApplic"/>
</jxb:bindings>
</jxb:bindings>-->
</jxb:bindings>
<jxb:bindings schemaLocation="elementGroups.xsd" node="//xs:group[#name='APPLIC']">
<jxb:bindings node=".//xs:choice//xs:sequence">
<jxb:bindings node=".//xs:choice">
<jxb:property name="assertEvalChoice" />
</jxb:bindings>
</jxb:bindings>
</jxb:bindings>
<jxb:bindings schemaLocation="dc.xsd" node="/xs:schema">
<jxb:bindings node="//xs:element[#name='language']">
<jxb:class name="DcLanguage" />
</jxb:bindings>
<jxb:bindings node="//xs:element[#name='subject']">
<jxb:class name="DcSubject" />
</jxb:bindings>
<jxb:bindings node="//xs:element[#name='title']">
<jxb:class name="DcTitle" />
</jxb:bindings>
</jxb:bindings>
</jxb:bindings>
A high level view of why this would occur and suggestions on how to fix it would be appreciated. I've only been using JAXB for a couple months and am not an expert. Thank you.
Here is the error I'm seeing:
javax.xml.bind.MarshalException
- with linked exception:
[com.sun.istack.SAXException2: unable to marshal type "com.synesis7.s7exporter.domain.s1000d.dm.common.XrefType" as an element because it is missing an #XmlRootElement annotation]
at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:323)
at com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:249)
at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:96)
at com.synesis7.s7exporter.client.s1000d.procedural.S7ProceduralRunnable.writeToXml(S7ProceduralRunnable.java:142)
at com.synesis7.s7exporter.client.s1000d.procedural.S7ProceduralRunnable.createProceduralDm(S7ProceduralRunnable.java:118)
at com.synesis7.s7exporter.client.s1000d.procedural.S7ProceduralRunnable.run(S7ProceduralRunnable.java:93)
at com.synesis7.s7exporter.S7ExporterController.processProceduralDms(S7ExporterController.java:235)
at com.synesis7.s7exporter.S7ExporterController.exportSchema(S7ExporterController.java:118)
at com.synesis7.s7exporter.S7exporter.initializeExporter(S7exporter.java:58)
at com.synesis7.s7exporter.S7exporter.main(S7exporter.java:38)
Caused by: com.sun.istack.SAXException2: unable to marshal type "com.synesis7.s7exporter.domain.s1000d.dm.common.XrefType" as an element because it is missing an #XmlRootElement annotation
at com.sun.xml.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:252)
at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot(ClassBeanInfoImpl.java:324)
at com.sun.xml.bind.v2.runtime.property.ArrayReferenceNodeProperty.serializeListBody(ArrayReferenceNodeProperty.java:118)
at com.sun.xml.bind.v2.runtime.property.ArrayERProperty.serializeBody(ArrayERProperty.java:159)
at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:344)
at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:700)
at com.sun.xml.bind.v2.runtime.property.ArrayElementNodeProperty.serializeItem(ArrayElementNodeProperty.java:69)
at com.sun.xml.bind.v2.runtime.property.ArrayElementProperty.serializeListBody(ArrayElementProperty.java:172)
at com.sun.xml.bind.v2.runtime.property.ArrayERProperty.serializeBody(ArrayERProperty.java:159)
at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:344)
at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:700)
at com.sun.xml.bind.v2.runtime.property.ArrayElementNodeProperty.serializeItem(ArrayElementNodeProperty.java:69)
at com.sun.xml.bind.v2.runtime.property.ArrayElementProperty.serializeListBody(ArrayElementProperty.java:172)
at com.sun.xml.bind.v2.runtime.property.ArrayERProperty.serializeBody(ArrayERProperty.java:159)
at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:344)
at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:700)
at com.sun.xml.bind.v2.runtime.property.ArrayElementNodeProperty.serializeItem(ArrayElementNodeProperty.java:69)
at com.sun.xml.bind.v2.runtime.property.ArrayElementProperty.serializeListBody(ArrayElementProperty.java:172)
at com.sun.xml.bind.v2.runtime.property.ArrayERProperty.serializeBody(ArrayERProperty.java:159)
at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:344)
at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:700)
at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:156)
at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:344)
at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:700)
at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:156)
at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:344)
at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:338)
at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:700)
at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:156)
at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:344)
at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:700)
at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:156)
at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl$1.serializeBody(ElementBeanInfoImpl.java:161)
at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl$1.serializeBody(ElementBeanInfoImpl.java:193)
at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeBody(ElementBeanInfoImpl.java:321)
at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeRoot(ElementBeanInfoImpl.java:328)
at com.sun.xml.bind.v2.runtime.ElementBeanInfoImpl.serializeRoot(ElementBeanInfoImpl.java:76)
at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:498)
at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:320)
... 9 more
You can wrap your object in an instance of JAXBElement to provide the root element information. If you generated your model from an XML schema there are convenience methods for this on the generated ObjectFactory class.
For More Information
http://blog.bdoughan.com/2012/07/jaxb-and-root-elements.html
You can use the ObjectFactory class to workaround for the classes which doesn't have the #XmlRootElement. ObjectFactory has overloaded methods to wrap it around the JAXBElement. Method:1 does the simple creation of the object and Method:2 will wrap the object with #JAXBElement. Always to use Method:2 to avoid javax.xml.bind.MarshalException - with linked exception missing an #XmlRootElement annotation
Method:1
public GetCountry createGetCountry() {
return new GetCountry();
}
Method:2
#XmlElementDecl(namespace = "my/name/space", name = "getCountry")
public JAXBElement<GetCountry> createGetCountry(GetCountry value) {
return new JAXBElement<GetCountry>(_GetCountry_QNAME, GetCountry.class, null, value);
}
hope this is will helpful...

XSD allow extension, compatibility and validation

I want to create an XSD for one application and another XSD wich extends the first (only by adding elements).
I want the XML file generated by the second application to be valid with the first one.
I tried this:
First XSD:
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns="example"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="example"
elementFormDefault="qualified" attributeFormDefault="qualified">
<xs:complexType name="typeA">
<xs:sequence>
<xs:element name="elA" type="xs:string" />
<xs:any namespace="##any" minOccurs="0" processContents="lax" />
</xs:sequence>
</xs:complexType>
<xs:element name="root" type="typeA" />
</xs:schema>
Second XSD:
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns="example"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="example">
<xs:redefine schemaLocation="firstXSD.xsd">
<xs:complexType name="typeA">
<xs:complexContent>
<xs:extension base="typeA">
<xs:sequence>
<xs:element name="newElement" type="xs:string" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:redefine>
</xs:schema>
Example of XML which must be valid with the first XSD (but not the second):
<?xml version="1.0" encoding="UTF-8" ?>
<root xmlns="example">
<elA>MyString</elA>
</root>
Example of XML which must be valid with both XSD
<?xml version="1.0" encoding="UTF-8" ?>
<root xmlns="example">
<elA>MyString</elA>
<newElement>MyNewString</newElement>
</root>
The previous XSD violate the "Unique Particle Attribution" and I want this to be fixed.
I can edit both XSD, but I want to be able to distribute the first one before finishing the second one.
How can I make this possible (both schemas must be valid when checked by JAXB) ?
Thanks
Some people may say: if you can edit both XSDs, why bother with redefine?
I'll show you how you can make it work with XSD redefine, at least from an XSD perspective. However, given limitations with JAXB, it’ll not work with it out of the box. If you also use automatic XSD refactoring, as an extra step, then you can make it work and, in the process, you'll be preserving the value proposition that you see when using xsd:redefine.
So, before that, here is another way which also uses composition, but without xsd:redefine; from a maintenance and validation perspective, you're getting about the same value and usage.
I'll refer to your first XSD as Model1 and your second XSD as Model2. I'll start with one XSD that will give you the "reuse-through-composition" aspect you have with xs:redefine.
Common items, xsd-allow-extension-compatibility-and-validation-common-items.xsd:
<?xml version="1.0" encoding="utf-8"?>
<!--XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com)-->
<xs:schema xmlns="example"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="example"
elementFormDefault="qualified" attributeFormDefault="qualified">
<xs:group name="typeA">
<xs:sequence>
<xs:element name="elA" type="xs:string" />
</xs:sequence>
</xs:group>
<xs:element name="root" type="typeA" />
</xs:schema>
Model1 "items", xsd-allow-extension-compatibility-and-validation-model1-items.xsd:
<?xml version="1.0" encoding="utf-8"?>
<!--XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com)-->
<xs:schema xmlns="example"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="example"
elementFormDefault="qualified" attributeFormDefault="qualified">
<xs:complexType name="typeA">
<xs:sequence>
<xs:group ref="typeA" />
<xs:any namespace="##any" minOccurs="0" processContents="lax" />
</xs:sequence>
</xs:complexType>
</xs:schema>
Model2 "items", xsd-allow-extension-compatibility-and-validation-model2-items.xsd:
<?xml version="1.0" encoding="utf-8"?>
<!--XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com)-->
<xs:schema xmlns="example"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="example"
elementFormDefault="qualified" attributeFormDefault="qualified">
<xs:complexType name="typeA">
<xs:sequence>
<xs:group ref="typeA" />
<xs:element name="newElement" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:schema>
If you pass Common Items and Model1, or Common Items and Model2 to JAXB compiler, it'll create the classes exactly the way you want. For easy of use (testing) and illustration, I've created two more XSDs:
Model1:
<?xml version="1.0" encoding="utf-8"?>
<!--XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com)-->
<xs:schema xmlns="example"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="example"
elementFormDefault="qualified" attributeFormDefault="qualified">
<xs:include schemaLocation="xsd-allow-extension-compatibility-and-validation-common-items.xsd"/>
<xs:include schemaLocation="xsd-allow-extension-compatibility-and-validation-model1-items.xsd"/>
</xs:schema>
Model2:
<?xml version="1.0" encoding="utf-8"?>
<!--XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com)-->
<xs:schema xmlns="example" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="example" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:include schemaLocation="xsd-allow-extension-compatibility-and-validation-common-items.xsd"/>
<xs:include schemaLocation="xsd-allow-extension-compatibility-and-validation-model2-items.xsd"/>
</xs:schema>
This is what you get when you run xjc agains Model1:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "typeA", propOrder = {
"elA",
"any"
})
public class TypeA {
#XmlElement(required = true)
protected String elA;
#XmlAnyElement(lax = true)
protected Object any;
/**
* Gets the value of the elA property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getElA() {
return elA;
}
/**
* Sets the value of the elA property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setElA(String value) {
this.elA = value;
}
/**
* Gets the value of the any property.
*
* #return
* possible object is
* {#link Element }
* {#link Object }
*
*/
public Object getAny() {
return any;
}
/**
* Sets the value of the any property.
*
* #param value
* allowed object is
* {#link Element }
* {#link Object }
*
*/
public void setAny(Object value) {
this.any = value;
}
}
... and when you run xjc agains Model2:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "typeA", propOrder = {
"elA",
"newElement"
})
public class TypeA {
#XmlElement(required = true)
protected String elA;
#XmlElement(required = true)
protected String newElement;
/**
* Gets the value of the elA property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getElA() {
return elA;
}
/**
* Sets the value of the elA property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setElA(String value) {
this.elA = value;
}
/**
* Gets the value of the newElement property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getNewElement() {
return newElement;
}
/**
* Sets the value of the newElement property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setNewElement(String value) {
this.newElement = value;
}
}
Model1 and Model2 XSDs will validate your XMLs exactly the way you've intended.
Below if a diagram showing the relationship between the XSD files. Green means "xsd:include", and the arrow points to the "included".
UPDATE: I just noticed, based on #Kevin 's comment, that you don't have a maxOccurs on your new element in the redefine. In this case, you could use one single redefine, like so:
<?xml version="1.0" encoding="utf-8"?>
<!--XML Schema generated by QTAssistant/XSR Module (http://www.paschidev.com)-->
<xsd:schema xmlns="example" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="example" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:redefine schemaLocation="xsd-allow-extension-compatibility-and-validation.xsd">
<xsd:complexType name="typeA">
<xsd:complexContent>
<xsd:restriction base="typeA">
<xsd:sequence>
<xsd:element name="elA" type="xsd:string" />
<xsd:element name="newElement" type="xsd:string" />
</xsd:sequence>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
</xsd:redefine>
</xsd:schema>
The only problem seems to be that JAXB (latest) still generates a class using the wildcard.
Update 2: Based on Kevin's comment, two avoid two redefines, a group should be used instead of xsd:any.
If you in fact plan to use more than one element to extend the new model, then read on. Below is the only way to do that, which requires the use of a group to further refine the any particles.
<?xml version="1.0" encoding="utf-8"?>
<!--XML Schema generated by QTAssistant/XSR Module (http://www.paschidev.com)-->
<xsd:schema xmlns="example" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="example" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:redefine schemaLocation="xsd-allow-extension-compatibility-and-validation.xsd">
<xsd:complexType name="typeA">
<xsd:complexContent>
<xsd:restriction base="typeA">
<xsd:sequence>
<xsd:element name="elA" type="xsd:string" />
<xsd:group ref="group1" minOccurs="0">
</xsd:sequence>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
</xsd:redefine>
<xsd:group name="group1">
<xsd:sequence>
<xsd:element name="newElement" type="xsd:string" />
</xsd:sequence>
</xsd:group>
</xsd:schema>
The net result is that the new XSD can be used to validate Model1, while the original file remains Model1.
What you actually want is a restriction. The wildcard is still part of the content model when you do extension, which is why you have a Unique Particle Attribution violation. What you are actually trying to do is replace the wildcard with something more restrictive, i.e. a particular element.

duplicate element not is detected with maven jaxb/jaxb2 plugin

I'm using maven-jaxb-plugin and maven-jaxb2-plugin to compile a xsd file that has two elements with same name, but the code compiles without throws an error. The generated class don't have the co-related properties. See the generated class:
...
* <element name="elementName" type="{http://namespace}typeElementName"/>
* <element name="elementName" type="{http://namespace}typeElementName"/>
public class TypeNameType {
#XmlElementRefs({
#XmlElementRef(name = "elementName", namespace = "http://namespace", type = JAXBElement.class)
})
protected List<JAXBElement<? extends Serializable>> content;
public List<JAXBElement<? extends Serializable>> getContent() {
if (content == null) {
content = new ArrayList<JAXBElement<? extends Serializable>>();
}
return this.content;
}
}
and XSD:
<schema elementFormDefault="qualified"
targetNamespace="http://namespace"
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://namespace">
<complexType name="typeNameType">
<sequence>
<element minOccurs="1" maxOccurs="1" name="elementName" type="string" />
<element minOccurs="1" maxOccurs="1" name="elementName" type="string" />
</sequence>
</complexType>
</schema>
Can anybody help me with this issue?
Tks!
Marcelo
Validating a bunch of xml files and xsd files as well, can be done by the xml-maven-plugin:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>xml-maven-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<goals>
<goal>validate</goal>
</goals>
</execution>
</executions>
<configuration>
<validationSets>
<validationSet>
<dir>src/main/xsd</dir>
<systemId>http://www.w3.org/2001/XMLSchema.xsd</systemId>
</validationSet>
</validationSets>
</configuration>
<plugin>
Havin all your xsd files below src/main/xsd the plugin will validate them against http://www.w3.org/2001/XMLSchema.xsd by runing mvn xml:validate. You should download the XMLSchema.xsd to your project to make validation faster and to skip the request to w3.org.

Resources