Generating Java Classes from IFC4 XSD Schema


To generate Java classes representing IFC Objects using IFC4 schema, I tried many ways and I got through this by using XJC XML Binding. But since JAXB is getting confused compiling the complex schema we have to specify confusing bindings in a separate file and provide it as a supporting file to solve the confusions.

if you run the following command it will get confused about the Path property.
(The -d is where the generated classes should be placed and -p is the package name of the classes being generated.)

$ xjc -d src/ -p com.test ifcXML4.xsd
parsing a schema…
[ERROR] Property “Path” is already defined. Use to resolve this conflict.
line 8381 of file:/media/isuru/Projects/stuff/ifcXML4.xsd
[ERROR] The following location is relevant to the above error
line 12910 of file:/media/isuru/Projects/stuff/ifcXML4.xsd
Failed to parse a schema.

To solve this add the following bindings.xjb file to the same folder where the schema is.

<?xml version="1.0" encoding="UTF-8"?>
<bindings xmlns="http://java.sun.com/xml/ns/jaxb"
xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="2.1">
<bindings schemaLocation="ifcXML4.xsd" version="1.0">
<schemaBindings>
<package name="com.test"/>
</schemaBindings>
<bindings node="//xs:attributeGroup[@name='instanceAttributes']">
<bindings node=".//xs:attribute[@name='path']">
<property name="pathAttribute"/>
</bindings>
</bindings>
</bindings>
</bindings>

Then when you run the following command, providing the bindings.xjb you can see the compiler get confused about ObjectFactory class.

$ xjc -p com -d src ifcXML4.xsd -b bindings.xjb
parsing a schema…
compiling a schema…
[ERROR] Two declarations cause a collision in the ObjectFactory class.
line 5214 of file:/media/isuru/Projects/stuff/ifcXML4.xsd
[ERROR] (Related to above error) This is the other declaration.
line 5190 of file:/media/isuru/Projects/stuff/ifcXML4.xsd
Failed to produce code.

Then to overcome this ObjectFactory problem add the following snippet to bindings.xjb

<bindings node="//xs:element[@name='IfcProductRepresentation']">
<class name="ifc:IfcProductRepresentation"/>
</bindings>

Adding above binding will make the final binding.xjb as follows,

<?xml version="1.0" encoding="UTF-8"?>
<bindings xmlns="http://java.sun.com/xml/ns/jaxb"
xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="2.1">
<bindings schemaLocation="ifcXML4.xsd" version="1.0">
<schemaBindings>
<package name="com.test"/>
</schemaBindings>
<bindings node="//xs:attributeGroup[@name='instanceAttributes']">
<bindings node=".//xs:attribute[@name='path']">
<property name="pathAttribute"/>
</bindings>

<bindings node="//xs:element[@name='IfcProductRepresentation']">
<class name="ifc:IfcProductRepresentation"/>
</bindings>
</bindings>
</bindings>
</bindings>

And to generate Java classes from IFC4 xsd use the following command,

xjc -p com.package.name -d src ifcXML4.xsd -b bindings.xjb

If you don’t use -p arg, it will use the package name specify in the schemaBindings tag of the bindings.xjb file.

Resources:
https://jaxb.java.net/nonav/2.2.5-5/docs/ch03.html
http://stackoverflow.com/questions/27939612/xjc-error-two-declarations-cause-a-collision-on-valid-xsd