Apache CXF Generated JAXB class has #XMLElement with Blank/Empty "" Namespace for External Schema/XSD - 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.

Related

How to get JAXB (xjc) to stop adding underscores between characters and numbers

In my code I need to map enumerated types from an XML file based on my schema to an enumerated type in another part of the code and vice versa.
The problem is that a construct like:
<simpleType name="sensorKindType">
<restriction base="string">
<enumeration value="ATS_S2_VOLTAGE_1_2" />
<enumeration value="ATS_S2_VOLTAGE_2_3" />
</restriction>
</simpleType>
Will cause the following to be generated.
#XmlEnumValue("ATS_S2_VOLTAGE_1_2")
ATS_S_2_VOLTAGE_1_2("ATS_S2_VOLTAGE_1_2"),
#XmlEnumValue("ATS_S2_VOLTAGE_2_3")
ATS_S_2_VOLTAGE_2_3("ATS_S2_VOLTAGE_2_3"),
However, what I would prefer is to have the following:
#XmlEnumValue("ATS_S2_VOLTAGE_1_2")
ATS_S2_VOLTAGE_1_2("ATS_S2_VOLTAGE_1_2"),
#XmlEnumValue("ATS_S2_VOLTAGE_2_3")
ATS_S2_VOLTAGE_2_3("ATS_S2_VOLTAGE_2_3"),
In other words, no underscore between the S and the 2.
You can control the names of the generated enums using a custom JAXB binding. If you have access to the schema, then you can inline these bindings in the schema as shown below. If you don't have access to the schema then you can define these preferences in an external bindings file.
<xs:schema elementFormDefault="qualified"
targetNamespace="stackoverflow"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
jaxb:version="2.1"
xsi:schemaLocation=
"http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd">
<xs:simpleType name="sensorKindType">
<xs:restriction base="xs:string">
<xs:enumeration value="ATS_S2_VOLTAGE_1_2">
<xs:annotation>
<xs:appinfo>
<jaxb:typesafeEnumMember name="ATS_S2_VOLTAGE_1_2"/>
</xs:appinfo>
</xs:annotation>
</xs:enumeration>
<xs:enumeration value="ATS_S2_VOLTAGE_2_3">
<xs:annotation>
<xs:appinfo>
<jaxb:typesafeEnumMember name="ATS_S2_VOLTAGE_2_3"/>
</xs:appinfo>
</xs:annotation>
</xs:enumeration>
</xs:restriction>
</xs:simpleType>
This worked fine for me with the default settings for the JAXB maven plugin with the snippet below in your pom file:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<id>xjc</id>
<goals>
<goal>xjc</goal>
</goals>
</execution>
</executions>
</plugin>
The following type is generated:
#XmlType(name = "sensorKindType", namespace = "stackoverflow")
#XmlEnum
public enum SensorKindType {
ATS_S2_VOLTAGE_1_2,
ATS_S2_VOLTAGE_2_3;
public String value() {
return name();
}
public static SensorKindType fromValue(String v) {
return valueOf(v);
}
}

how to generate #TABLE tags using jaxb2 maven plugin

Hi I have followed some tutorials and written a schema which is as follows :
<xs:element name="User" type="kmcs:User"/>
<xs:element name="UserList" type="kmcs:UserList"/>
<xs:complexType name="User">
<xs:sequence>
<xs:element name="id" type="xs:long" minOccurs="0" />
<xs:element name="name" type="xs:string" />
<xs:element name="registrationDate" type="xs:dateTime" />
</xs:sequence>
<xs:attribute name = ""/>
</xs:complexType>
<xs:complexType name="UserList">
<xs:complexContent>
<xs:extension base="kmcs:User">
<xs:sequence>
<xs:element name="user" minOccurs="0"
maxOccurs="unbounded" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
It generates the following :
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "User", propOrder = {
"id",
"name",
"registrationDate"
})
#XmlSeeAlso({
UserList.class
})
#Entity
#XmlRootElement(name = "{#id}")
#Table(schema = "schemaname", uniqueConstraints = {
}, name = "BillingAccountNumberDetailsInfo")
public class User
implements Serializable, ToString
{
I wanted something like this :
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "User", propOrder = {
"id",
"name",
"registrationDate"
})
#XmlSeeAlso({
UserList.class
})
#Entity
#XmlRootElement(name ="user")
#Table(schema = "schema_name", uniqueConstraints = {
}, name = "User")
public class User
implements Serializable, ToString
{
So what I wanted is basically the table name which it picks whatever I provide as hard coded but I wanted it to show the class name or class object name .
Use this configuration.
<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="../yourSchema.xsd">
<bindings node="//xs:complexType[#name='User']">
<annox:annotate>
<annox:annotate annox:class="javax.persistence.Entity">
</annox:annotate>
<annox:annotate annox:class="javax.persistence.Table" schema = "schema_name" name = "User">
</annox:annotate>
<annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement"
name="User">
</annox:annotate>
</annox:annotate>
</bindings>
</bindings>
</bindings>
the maven plugin configuration is
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.8.1</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<args>
<arg>-Xannotate</arg>
<arg>-nv</arg>
<arg>-Xnamespace-prefix</arg>
</args>
<extension>true</extension>
<schemaDirectory>src/main/resources/schema</schemaDirectory>
<schemaIncludes>
<schemaInclude>yourSchema.xsd</schemaInclude>
</schemaIncludes>
<bindingDirectory>src/main/resources/schema/xjb</bindingDirectory>
<bindingIncludes>
<include>*.xjb</include>
</bindingIncludes>
<debug>true</debug>
<verbose>true</verbose>
<episode>true</episode>
<forceRegenerate>true</forceRegenerate>
<plugins>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>0.6.0</version>
</plugin>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics-annotate</artifactId>
<version>0.6.0</version>
</plugin>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-namespace-prefix</artifactId>
<version>1.1</version>
</plugin>
</plugins>
</configuration>
<dependencies>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>1.0.1.Final</version>
</dependency>
</dependencies>
</plugin>

JAXB Unmarshal - Elements missing and elements in not in order

I am trying to unmarshal an XML that I marshalled before.
In the unmarshalled result, I am missing elements and the elements I get are not in the same order as the input XML. I've created a afterUnmarshal() listener and I see the elements there, but not in the resulting Java Object.
The XSD is structured like this (a 'fanout'-node, for example, can contain another set of processSteps, so it can be deeply nested (tree)):
<xsd:element name="process">
<xsd:annotation>
<xsd:documentation>Integration Process</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<!-- more -->
<xsd:element name="itinerary" type="lwis:itineraryType"/>
<!-- more -->
</xsd:complexType>
</xsd:element>
<xsd:complexType name="itineraryType">
<xsd:sequence>
<xsd:element name="step" type="lwis:stepType"/>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="step" type="lwis:stepType"/>
<xsd:element name="fanout" type="lwis:fanoutType"/>
<xsd:element name="decision">
<xsd:complexType>
<!-- snip.. -->
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:sequence>
</xsd:complexType>
I suppose the order is given by the SAX parser, but I can't imagine a SAX parser would change the order for no reason? At the moment, the first element in the list is the last one in the XML. The second element in the list is the third in the XML - it seems random..
Thanks for any help!
Sample Input:
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
<process name="My.Process" description="My Process description" qualityOfService="AT_LEAST_ONCE" entryEndpoint="ENTRY.EP" xmlns="http://www.xxxxx.com/ns/yyyy">
<faultEndpoint endpoint_ref="EXIT.EP"/>
<rejectEndpoint endpoint_ref="EXIT.EP"/>
<itinerary>
<step name="Step 1" endpoint_ref="Step1.EP" type="SERVICE"/>
<step name="Step2-CBRStep" endpoint_ref="Step2.EP" type="SERVICE"/>
<decision name="Decision-nonameneeded">
<option name="op1">
<step name="Step 2A" endpoint_ref="Step2a.EP" type="SERVICE"/>
</option>
<option name="op2">
<step name="Step 2B" endpoint_ref="Step2a.EP" type="SERVICE"/>
</option>
</decision>
<step name="Step 3" endpoint_ref="Step3.EP" type="SERVICE"/>
<fanout name="Fan1">
<path>
<step name="Step4A" endpoint_ref="Step4A.EP" type="SERVICE"/>
</path>
<path>
<step name="Step4B" endpoint_ref="Step4B.EP" type="SERVICE"/>
<step name="Step5" endpoint_ref="Step5.EP" type="SERVICE"/>
</path>
</fanout>
<step name="Step6" endpoint_ref="Step6.EP" type="SERVICE"/>
</itinerary>
</process>
Object:
Process Object has a field with itinerary of Type ItineraryType which:
step = StepType ("Step6" from XML)
stepOrFanoutOrDecision = ArrayList:
item 0: ItineraryType$Decision ("Decision-nonameneeded" from XML)
option 0: "op1" from XML
step: "Step 2A" from XML
option 1: "op2" from XML
step: "Step 2B" from XML
item 1: FanoutType ("Fan1" from XML)
path 0:
step: Step4A
path 1:
step: Step5
Step 1, Step2-CBRStep and Step 4B is missing?
I have the toString() output of the itinerary here:
com.x.ItineraryType#fe39ebf[step=com.x.StepType#28cb15bf[endpointRef=Step6.EP, type=SERVICE, params=<null>, paramsRef=<null>, name=Step6, description=<null>], stepOrFanoutOrDecision={com.x.ItineraryType$Decision#2d00c385[option={com.x.ItineraryType$Decision$Option#d2467d8[step=com.x.StepType#511d9ca5[endpointRef=Step2a.EP, type=SERVICE, params=<null>, paramsRef=<null>, name=Step 2A, description=<null>], stepOrFanoutOrDecision=<null>, name=op1],com.x.ItineraryType$Decision$Option#6f173e3d[step=com.x.StepType#5ef74fc5[endpointRef=Step2a.EP, type=SERVICE, params=<null>, paramsRef=<null>, name=Step 2B, description=<null>], stepOrFanoutOrDecision=<null>, name=op2]}, name=Decision-nonameneeded, description=<null>],com.x.FanoutType#3e963f38[path={com.x.FanoutType$Path#7a1095a1[step=com.x.StepType#56cfbba2[endpointRef=Step4A.EP, type=SERVICE, params=<null>, paramsRef=<null>, name=Step4A, description=<null>], stepOrFanoutOrDecision=<null>, name=<null>],com.x.FanoutType$Path#6027b534[step=com.x.StepType#4ee99a3d[endpointRef=Step5.EP, type=SERVICE, params=<null>, paramsRef=<null>, name=Step5, description=<null>], stepOrFanoutOrDecision=<null>, name=<null>]}, name=Fan1, description=<null>]}]
Ant Script I'm using: with extensions hashCode, toString and equals:
<?xml version="1.0" encoding="UTF-8"?>
<project name="RunningXjc" default="generate-sources" basedir=".">
<description>Runs Xjc Binding Compiler</description>
<target name="generate-sources">
<taskdef name="xjc" classname="org.jvnet.jaxb2_commons.xjc.XJC2Task">
<classpath>
<fileset dir="buildLib/jaxb-ri-2.2.6/lib">
<include name="*" />
</fileset>
<fileset dir="buildLib/jaxb2-basics-dist-0.6.4/dist">
<include name="jaxb2-basics-ant-*.jar" />
</fileset>
</classpath>
</taskdef>
<!-- Generate the Java code for XSD -->
<xjc destdir="${basedir}/target/generated-sources/xjc" extension="true">
<arg
line="
-Xequals
-XhashCode
-XtoString
-Xcopyable
-Xmergeable" />
<binding dir="${basedir}/src">
<include name="**/*.xjb" />
</binding>
<schema dir="${basedir}/schema">
<include name="processSlim.xsd" />
</schema>
<!-- Plugins -->
<classpath>
<fileset dir="${basedir}/buildLib/jaxb2-basics-dist-0.6.4">
<!-- JAXB2 Basics library -->
<include name="dist/jaxb2-basics-*.jar" />
<!-- JAXB2 Basics library dependencies -->
<include name="dist/jaxb2-basics-runtime-*.jar" />
<include name="dist/jaxb2-basics-tools-*.jar" />
<include name="lib/commons-beanutils-*.jar" />
<include name="lib/commons-lang-*.jar" />
<include name="lib/commons-logging-*.jar" />
<include name="lib/javaparser-*.jar" />
<include name="lib/annox-*.jar" />
</fileset>
</classpath>
</xjc>
</target>
</project>
PROBLEM
From Your XML Schema
Below is a fragment from your XML schema. The itineraryType contains a sequence where a step element can occur both inside and outside of the choice structure.
<xsd:complexType name="itineraryType">
<xsd:sequence>
<xsd:element name="step" type="lwis:stepType" />
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="step" type="lwis:stepType" />
<xsd:element name="fanout" type="lwis:fanoutType" />
<xsd:element name="decision">
<xsd:complexType>
<!-- snip.. -->
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:sequence>
</xsd:complexType>
ItineraryType
This is causing the step element to be mapped to two different properties which is causing your problem.
public class ItineraryType {
#XmlElement(required = true)
protected StepType step;
#XmlElements({
#XmlElement(name = "step", type = StepType.class),
#XmlElement(name = "fanout", type = FanoutType.class),
#XmlElement(name = "decision", type = ItineraryType.Decision.class)
})
protected List<Object> stepOrFanoutOrDecision;
...
}
SOLUTION
You can use the simple binding mode extension in the JAXB XJC tool to support this use case. It will automatically prevent the step property from being created. You can specify this via an external binding document like the following:
bindings.xml
<jxb:bindings
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jxb:extensionBindingPrefixes="xjc"
version="2.1">
<jxb:globalBindings>
<xjc:simple />
</jxb:globalBindings>
</jxb:bindings>
XJC Call
Below is how the external bindings file is referenced in an XJC call. You will need to also use the -extension flag to enable the XJC extension to be used.
xjc -extension -b bindings.xml schema.xsd

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