Reputation: 195
Here is how my xsd looks:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="unqualified"
attributeFormDefault="unqualified">
<xs:element name="Root">
<xs:complexType>
<xs:sequence>
<xs:element name="Rooms">
<xs:complexType>
<xs:sequence maxOccurs="unbounded">
<xs:element name="Room">
<xs:complexType>
<xs:sequence>
<xs:element name="Metadata">
<xs:complexType>
<xs:sequence>
<xs:element name="Room">
...
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Here is my xsd2java task config:
task xsd2java {
def jaxbTargetDir = file("src/main/java")
def bindingFile = file('src/main/resources/jaxb/bindings.xml') // Specify the path to your bindings.xml
doLast {
jaxbTargetDir.mkdirs()
ant.taskdef(name: 'xjc', classname: 'com.sun.tools.xjc.XJCTask', classpath: configurations.xsd2java.asPath)
ant.jaxbTargetDir = jaxbTargetDir
ant.xjc(destdir: '${jaxbTargetDir}',
package: 'com.project.schema',
schema: 'src/main/resources/xsd/sample.xsd',
binding: bindingFile,
extension: 'true')
}
}
compileJava.dependsOn 'xsd2java'
Here is how the generated class looks like:
public class Root {
public static class Rooms {
public static class Room {
public static class Metadata {
public static class Room { ;
}
}
}
}
}
You can already see that its creating multiple classes with same name. There is a Room
class duplicated and nested inside Metadata
which is inside Room
. This is throwing an error as Java cannot allow duplicate classnames. So, I have resorted to using binding files to change the inner classname from Room
to MetadataRoom
.
Here is my binding file:
<jaxb:bindings xmlns:jaxb="https://jakarta.ee/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
jaxb:version="3.0">
<jaxb:bindings schemaLocation="../xsd/sample.xsd">
<jaxb:bindings node="//xs:element[@name='Root']//xs:element[@name='Rooms']//xs:element[@name='Room']//xs:element[@name='Metadata']//xs:element[@name='Room']">
<jaxb:class name="MetadataRoom"/>
</jaxb:bindings>
</jaxb:bindings>
</jaxb:bindings>
When I try to use this, it throws an error that says:
Execution failed for task ':xsd2java'.
> java.lang.IllegalArgumentException: Illegal class inheritance loop. Outer class MetadataRoom may not subclass from inner class: MetadataRoom
Im not an XSD, or JAXB expert, so I need guidance in this.
I also tried changing the outer Room
's classname through the JXB binding, but it throws:
[ant:xjc] [ERROR] XPath evaluation of "//xs:element[@name='Root']//xs:element[@name='Rooms']//xs:element[@name='Room']" results in too many (2) target nodes
Upvotes: 0
Views: 29
Reputation: 195
https://stackoverflow.com/a/32773096/18054760 this answered my question. Apparently, we should access xs:complexType
as that is what JAXB uses to generate classnames not the elements themselves.
Upvotes: 0