I have two XSD documents over which I have no control - i.e. I cannot force their authors to change them. Unfortunately, the XSDs are not valid when used side by side, because they contain conflicting definitions:
<!-- first.xsd -->
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:onl="http://example/data/online" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://example/data/online" elementFormDefault="qualified" attributeFormDefault="unqualified" version="2.4">
<xs:element name="content">
<xs:complexType>
<xs:sequence>
<xs:element name="docSeqId" type="xs:long">
<xs:annotation>
<xs:documentation>Identifier of a documentation sequence.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="customerName" type="xs:string">
<xs:annotation>
<xs:documentation>Name of a customer.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
<!-- second.xsd -->
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:onl="http://example/data/online" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://example/data/online" elementFormDefault="qualified" attributeFormDefault="unqualified" version="2.4">
<xs:element name="content">
<xs:complexType>
<xs:sequence>
<xs:element name="transactionId" type="xs:long">
<xs:annotation>
<xs:documentation>Id of a transaction.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="amount" type="xs:decimal">
<xs:annotation>
<xs:documentation>Transaction amount.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="targetAccountId" type="xs:string">
<xs:annotation>
<xs:documentation>Id (GUID) of a target account.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
I created the following jaxb2-maven-plugin configuration:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<outputDirectory>${project.build.directory}/generated-sources/</outputDirectory>
</configuration>
<executions>
<execution>
<id>generate-source-code</id>
<goals>
<goal>xjc</goal>
</goals>
<configuration>
<sources>
<source>src/main/resources/integration/first.xsd</source>
<source>src/main/resources/integration/second.xsd</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
but when I execute relevant maven phase, the build exits with the following error:
[ERROR] file:/C:/Users/Andy/development/sample-project/src/main/resources/integration/second.xsd [23,18] org.xml.sax.SAXParseException: 'content' is already defined
How can I generate valid Java code from the XSD files, so that I can use them?
I figured out I was facing two issues:
Contentclass in a same package - which obviously does not work,jaxb2-maven-pluginto process them simultaneously.In order to solve the first of the two problems, I use two
.xjb(XML-to-Java binding file, one for each of the invalid.xsds), where I defined in which Java package source code from a given.xsdshould be placed.The binding files look like this:
Using the binding, (among other things), I was able to override the target Java package.
I solved the second problem by creating two separate executions of the
jaxb2-maven-plugin, one for each of the conflicting.xsds, and each of them using their relevant.jxbbinding file.Important: By default,
jaxb2-maven-pluginclears the output directory before each generation execution. In my case I want to merge generated code together, this can be done by setting theclearOutputDirargument tofalse.The final configuration of the plugin looks like this:
leading to correct Java code generation: