Is there a way to deal with duplicate element definitions across multiple .xsd files in JAXB?

user177800 picture user177800 · Jul 13, 2011 · Viewed 21.9k times · Source

I have dozens and dozens .xsd files that I want to auto-generate code for. A couple of the files have duplicate names that clash when I try to generate all of them at the same time.

I am focusing on just trying to get 2 of these to work.

When I get these 2 working I will fix the rest. But I am just focusing on 2 of these files for now. I am not in control of them, they are from a vendor and follow a "standard", so editing them is not an option for multiple reasons.

I am using the maven-jaxb2-plugin to process these files.

I added a binding.xjb file as suggested in the link in mat b's answer and other instructions I have found on the web. But I am getting the following errors, an no output.

<?xml version="1.0" encoding="UTF-8"?>
<jxb:bindings version="2.1"
              xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
              xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
              xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
              xmlns:xs="http://www.w3.org/2001/XMLSchema"
              xsi:schemaLocation=" http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd">
  <jxb:bindings schemaLocation="mac-3.4.xsd">
    <jxb:schemaBindings>
      <jxb:package name="my.company.mac"/>
    </jxb:schemaBindings>
  </jxb:bindings>
  <jxb:bindings schemaLocation="mac-stylesheet-3.4.xsd">
    <jxb:schemaBindings>
      <jxb:package name="my.company.stylesheet"/>
    </jxb:schemaBindings>
  </jxb:bindings>
</jxb:bindings>

gives the following error

[ERROR] Error while parsing schema(s).Location [ file:/C:/Users/Jarrod%20Roberson/Projects/spa-tools/spa-lib/src/main/sc
hema/mac-stylesheet-3.4.xsd{165,33}].
org.xml.sax.SAXParseException: 'halign' is already defined

The offending element is : ( there are many others this is just the first one that clashes )

<xsd:simpleType name="halign">
  <xsd:restriction base="xsd:string">
    <xsd:enumeration value="left" />
    <xsd:enumeration value="center" />
    <xsd:enumeration value="right" />
  </xsd:restriction>
</xsd:simpleType>

And is identical in each of the .xsd files, how do I resolve this duplication with either only one class being generated or each one being generated in to their own package namespace?

This isn't the only duplicate element like this there are lots of them, so just trying to remove them from the files isn't a option either.

This halign is in multiple .xsd files and I want to either put them in their individual packages, or be able to tell the compiler to use the first one that was generated.

This is where I started off before I tried an external .xjb file, by just specifying the package in the pom.xml.

How do I configure the binding to either ignore the duplicate configurations, map them to separate packages or map them to existing implementations?

Answer

user177800 picture user177800 · Jul 14, 2011

I have a half-way workaround solution to this, but it is very time intensive. I had to create a separate <execution/> for every one of the files that has duplicate entries.

<executions>
  <execution>
    <id>jaxb-mac</id>
    <phase>generate-sources</phase>
    <goals>
      <goal>generate</goal>
    </goals>
    <configuration>
      <forceRegenerate>true</forceRegenerate>
      <generatePackage>my.company.mac</generatePackage>
      <schemaDirectory>src/main/schema</schemaDirectory>
      <schemaIncludes>
        <include>mac-3.4.xsd</include>
      </schemaIncludes>
    </configuration>
  </execution>
  <execution>
    <id>jaxb-stylesheet</id>
    <phase>generate-sources</phase>
    <goals>
      <goal>generate</goal>
    </goals>
    <configuration>
      <forceRegenerate>true</forceRegenerate>
      <generatePackage>my.company.stylesheet</generatePackage>
      <schemaDirectory>src/main/schema</schemaDirectory>
      <schemaIncludes>
        <include>mac-stylesheet-3.4.xsd</include>
      </schemaIncludes>
    </configuration>
  </execution>

The <forceRegenerate>true</forceRegenerate> is important or only the first <execution/> will run and the rest will think that there is no need to run because I am generating into the same directory.

I would still like a less labor intensive solution to deal with the duplicates.

I think if I make the first master .xsd a separate module that builds into its own .jar file, I could then use the <episode/> tag and have it skip generating the same duplicate elements over and over, since they are identical in definition.

I have since decided to abandon XML if at all possible and JAXB completely. There are newer and better ways to parse XML and map it to objects as of this edit.