Posts Tagged ‘xsd’

Generating JAXB classes from a xsd schema in a Maven project

If you want to geenrate JAXB classes from a xsd schema in a Maven project, you need to specify the dependencies for jaxb and the plugin.

The pom.xml file is like the following:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>de.demo.maven.jaxb</groupId>
	<artifactId>MAVEN_JAXB_DEMO</artifactId>
	<version>0.0.1-SNAPSHOT</version>

<dependencies>
<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.2.5</version>
</dependency>
<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
    <version>2.2.5</version>
</dependency>
</dependencies>
	
 <build>
    <plugins>
        <!-- JAXB xjc plugin that invokes the xjc compiler to compile XML schema into Java classes.-->
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>jaxb2-maven-plugin</artifactId>
            <executions>
                <execution>
                    <goals>
                        <goal>xjc</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <!-- The schema directory or xsd files. -->
                <schemaDirectory>${basedir}/src/main/resources</schemaDirectory>
                <!-- The package in which the source files will be generated. -->
                <packageName>de.demo.team</packageName>
                <!-- The working directory to create the generated java source files. -->
                <outputDirectory>${basedir}/src/main/java</outputDirectory>
            </configuration>
        </plugin>
    </plugins>
  </build>
	
</project>

in the configuration tags you need to specify “schemaDirectory” (the location of the .xsd file) and in the “outputDirectory” the destination folder for the generated classes.

First of all you need to run the maven compile command. Then you can generate the JAXB classes: in eclipse, for example, you can right-click on the project and run New>Other>JAXB>”JAXB Classes from a Schema”.
Of course you need to add the Eclipse plugin first.

Eclipse won´t generate automatically the @XmlRootElement annotation. You will have to add it on your own, like this:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "MBean", propOrder = {
    "attribute"
})
@XmlRootElement
public class MBean {
...
}

JAXB – TEAM EXAMPLE – PART 1: XSD schema with root attribute and child element with attribute and value

In this post I will show you how to represent an XSD schema with root attribute and child element with attribute and value. For example, let´s consider a software development team:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<team category="software development">
    <Member role="junior">Laura</Member>
    <Member role="senior">Erik</Member>
    <Member role="graduate">Mike</Member>
</team>

The xsd schema generally represent a a working team :

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
	targetNamespace="http://acme.com/schema/type/team/v1" xmlns:team="http://acme.com/schema/type/team/v1"
	xmlns:company="http://acme.com/schema/type/company/v1"
	elementFormDefault="qualified">

	<xsd:element name="Team" type="team:Team" />

	<xsd:complexType name="Team">
		<xsd:annotation>
			<xsd:documentation>Represents a working team </xsd:documentation>
		</xsd:annotation>
		<xsd:sequence maxOccurs="unbounded">
			<xsd:element name="Member">
				<xsd:complexType>
					<xsd:simpleContent>
						<xsd:extension base="xsd:string">
							<xsd:attribute name="role" type="xsd:string" />
						</xsd:extension>
					</xsd:simpleContent>
				</xsd:complexType>
			</xsd:element>
		</xsd:sequence>
		<xsd:attribute name="category" type="xsd:string" />
	</xsd:complexType>
</xsd:schema>

Although it seems to be a typical case, I have spent several hours reading books, tutorials and forum, trying to map a web service xml file with such a structure.
I have finally found the solution on a google forums post.

A better solution would be using the type attribute and make a separate “complexType” tag, because in this way JAXB would be able to create a different bean class for each element (also the nested ones). So an equivalent version of the schema is the following:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
	targetNamespace="http://acme.com/schema/type/team/v1" xmlns:team="http://acme.com/schema/type/team/v1"
	xmlns:company="http://acme.com/schema/type/company/v1"
	elementFormDefault="qualified">

	<xsd:element name="Team" type="team:Team" />

	<xsd:complexType name="Team">
		<xsd:annotation>
			<xsd:documentation>Represents a working team </xsd:documentation>
		</xsd:annotation>
		<xsd:sequence>
			<xsd:element name="Member" type="team:member" minOccurs="0"
				maxOccurs="unbounded" />
		</xsd:sequence>
		<xsd:attribute name="category" type="xsd:string" />
	</xsd:complexType>
	
	<xsd:complexType name="member">
		<xsd:simpleContent>
			<xsd:extension base="xsd:string">
				<xsd:attribute name="role" type="xsd:string" />
			</xsd:extension>
		</xsd:simpleContent>
	</xsd:complexType>

</xsd:schema>

In eclipse, downloading the “m2e conntector for jaxb” plugin, you can automatically generate all the object classes from your XSD schema (in the menu bar menu you can find the JAXB section under File>New>…). Without a binding file, you will have to add the “@XmlRootElement” annotation on the top of your root element class and also delete the namespace in the package-info class. I will tell you more in the next posts…

Categories
Links: