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.
Related
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.
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);
}
}
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>
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/
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.