Create Java classes with JaxB - java

I tried to create Java classes with JaXB from this XSD http://pda.rosreestr.ru/upload/www/files/02_V04_STD_Region_Cadastr_KV.rar but got these errors.
parsing a schema...
[WARNING] Simple type "dAllDocuments" was not mapped to Enum due to EnumMemberSizeCap limit. Facets count: 298, current limit: 256. You can use customization attribute "typesafeEnumMaxMembers" to extend the limit.
line 3 of file:/D:/liferay-develop/workspace/JABX_test/src/02_V04_STD_Region_Cadastr_KV/dAllDocuments.xsd
compiling a schema...
[ERROR] Two declarations cause a collision in the ObjectFactory class.
line 1645 of file:/D:/liferay-develop/workspace/JABX_test/src/02_V04_STD_Region_Cadastr_KV/STD_Region_Cadastr_KV.xsd
[ERROR] (Related to above error) This is the other declaration.
line 1587 of file:/D:/liferay-develop/workspace/JABX_test/src/02_V04_STD_Region_Cadastr_KV/STD_Region_Cadastr_KV.xsd
Failed to produce code.
When I work with another schemas everything is fine. I am not good in work with XML, can you tell me what these errors mean and how to solve it?
UPDATE
I tried to use binding.xml in class generation but got this error.
C:\Documents and Settings\kliver\Мои документы\Загрузки\jaxb-ri-2.2.6\bin>xjc -d
out -b binding.xml D:/liferay-develop/workspace/JABX_test/src/02_V04_STD_Region
_Cadastr_KV/STD_Region_Cadastr_KV.xsd
parsing a schema...
[ERROR] "D:/liferay-develop/workspace/JABX_test/src/02_V04_STD_Region_Cadastr_KV
/STD_Region_Cadastr_KV.xsd" is not a part of this compilation. Is this a mistake
for "file:/D:/liferay-develop/workspace/JABX_test/src/02_V04_STD_Region_Cadastr
_KV/STD_Region_Cadastr_KV.xsd"?
line 6 of file:/C:/Documents%20and%20Settings/kliver/%D0%9C%D0%BE%D0%B8%20%D0%
B4%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D1%8B/%D0%97%D0%B0%D0%B3%D1%80%D1%8
3%D0%B7%D0%BA%D0%B8/jaxb-ri-2.2.6/bin/binding.xml
[WARNING] Simple type "dAllDocuments" was not mapped to Enum due to EnumMemberSi
zeCap limit. Facets count: 298, current limit: 256. You can use customization at
tribute "typesafeEnumMaxMembers" to extend the limit.
line 3 of file:/D:/liferay-develop/workspace/JABX_test/src/02_V04_STD_Region_C
adastr_KV/dAllDocuments.xsd
Failed to parse a schema.
UPDATE2
I try this binding:
<jxb:bindings
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
version="2.1">
<!-- Raise theEnumMemberSizeCap limit -->
<jxb:bindings >
<jxb:globalBindings typesafeEnumMaxMembers="2000"/>
</jxb:bindings>
<jxb:bindings schemaLocation="D:\liferay-develop\workspace\JABX_test\src\02_V04_STD_Region_Cadastr_KV\STD_Region_Cadastr_KV.xsd">
<jxb:bindings node="//xs:complexType[#name='tRight_Owner']">
<jxb:class name="tRight_Owner2"/>
</jxb:bindings>
</jxb:bindings>
</jxb:bindings>
And this console command:
C:\Documents and Settings\kliver\Мои документы\Загрузки\jaxb-ri-2.2.6\bin>xjc -d
out -b binding.xml D:\liferay-develop\workspace\JABX_test\src\02_V04_STD_Region
_Cadastr_KV\STD_Region_Cadastr_KV.xsd

You can use an external bindings file to specify a different class name for one of the complex types.
binding.xml
<jxb:bindings
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
version="2.1">
<!-- Raise theEnumMemberSizeCap limit -->
<jxb:bindings >
<jxb:globalBindings typesafeEnumMaxMembers="2000"/>
</jxb:bindings>
<jxb:bindings schemaLocation="your-schema.xsd">
<jxb:bindings node="//xs:complexType[#name='tRight_Owner']">
<jxb:class name="TRight_Owner2"/>
</jxb:bindings>
</jxb:bindings>
</jxb:bindings>
The xjc command line would be:
xjc -d out -b binding.xml your-schema.xsd

For those of you coming across this question in later years this method worked for me.
Environment: Netbeans 7.4
Build method: Maven - jaxb2-maven-plugin
Create a folder called xjb in src\main.
In that folder create a file called binding.xjb (or any other .xjb name).
In it:
<jxb:bindings
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
version="2.1">
<!-- Raise theEnumMemberSizeCap limit -->
<jxb:bindings >
<jxb:globalBindings typesafeEnumMaxMembers="2000"/>
</jxb:bindings>
</jxb:bindings>
Note that this is not an alternative solution to Blaise's post.

I'm using version 0.13.0 of the maven-jaxb2-plugin, and I found the correct path to the binding file is:
src/main/resources/binding.xjb
The content is the same as OldCurmudgeon proposed, namely:
<jxb:bindings xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb" version="2.1">
<!-- Raise theEnumMemberSizeCap limit -->
<jxb:bindings>
<jxb:globalBindings typesafeEnumMaxMembers="2000" />
</jxb:bindings>
</jxb:bindings>

You have an issue with your XSD, there are multiple declarations of same name tRight_Owner
line 1587:
<xs:complexType>
<xs:complexContent>
<xs:extension base="tRight_Owner"/>
</xs:complexContent>
</xs:complexType>
line 1645:
<xs:complexType name="tRight_Owner">

Related

JAXB XJC: how to skip class generation for an imported namespace?

I'm generating the Java classes corresponding to the XML-Schema at
https://cwe.mitre.org/data/xsd/cwe_schema_v6.10.xsd
but most of the generated classes are undesired since they belong to the imported namespace:
<xs:import namespace="http://www.w3.org/1999/xhtml"
schemaLocation="http://www.w3.org/2002/08/xhtml/xhtml1-strict.xsd"/>
Indeed, if I simply comment out this import statement then the generated classes go from 149 (mostly HTML elements) to just 59 (all belonging to the input schema domain).
My question is if/how it is possible to skip/ignore the generation of Java classes for certain XML elements and in this case the elements defined in an imported namespace,
defining some custom rules in a .xjb file.
The solution available at https://stackoverflow.com/a/20907846/8737144 didn't work in my case, returning the following error
com.sun.istack.SAXParseException2: compiler was unable to honor this class customization. It is attached to a wrong place, or its inconsistent with other bindings.
It is possible to test the generation using the following command:
xjc http://www.w3.org/2002/08/xhtml/xhtml1-strict.xsd -b cwe-bindings.xjb
<!-- cwe-bindings.xjb -->
<jxb:bindings version="3.0"
xmlns:jxb="https://jakarta.ee/xml/ns/jaxb"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<jxb:bindings schemaLocation="http://www.w3.org/2002/08/xhtml/xhtml1-strict.xsd" node="//xsd:schema">
<jxb:schemaBindings>
<jxb:package name="com.example.cwe"/>
</jxb:schemaBindings>
<!-- rename the 'lang' attribute on line 302 to 'langAttribute' -->
<jxb:bindings node="//xsd:attributeGroup[#name='i18n']/xsd:attribute[#name='lang']">
<jxb:property name="langAttribute"/>
</jxb:bindings>
<!-- rename the 'lang' attribute on line 1166 to 'langAttribute' -->
<jxb:bindings node="//xsd:element[#name='bdo']/xsd:complexType/xsd:complexContent/xsd:extension/xsd:attribute[#name='lang']">
<jxb:property name="langAttribute"/>
</jxb:bindings>
</jxb:bindings>
</jxb:bindings>

JAXB/XJC external binding for renaming versus multiple XSD compile

(I've already googled it and done a search here and found no answer, maybe I'm using the wrong keywords...)
To make it simple, I have two schemas:
a.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://foo.bar/something"
targetNamespace="http://foo.bar/something"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xs:complexType name="TFoo">
<xs:attribute name="version" type="xs:string" />
</xs:complexType>
</xs:schema>
b.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://foo.bar/something"
targetNamespace="http://foo.bar/something"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xs:complexType name="TFoo">
<xs:attribute name="version" type="xs:string" />
<xs:attribute name="dateTime" type="xs:dateTime" />
</xs:complexType>
</xs:schema>
Both have the same targetNamespace and a complexType named TFoo.
I have an external binding to change the generated class name of a.xsd from TFoo to TFooA:
a-binding.xml:
<jxb:bindings
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
version="2.1">
<jxb:bindings schemaLocation="a.xsd">
<jxb:bindings node="//xs:complexType[#name='TFoo']">
<jxb:class name="TFooA"/>
</jxb:bindings>
</jxb:bindings>
</jxb:bindings>
which works if I compile the a.xsd alone:
$ xjc -b a-binding.xml a.xsd
parsing a schema...
compiling a schema...
bar/foo/something/ObjectFactory.java
bar/foo/something/TFooA.java
bar/foo/something/package-info.java
(look how I got TFooA.java)
But, if I try to compile both schemas at once, I get:
$ xjc -b a-binding.xml a.xsd b.xsd
parsing a schema...
[ERROR] 'TFoo' is already defined
line 13 of file:/home/scherrer/tmp/PL_008f/b.xsd
[ERROR] (related to above error) the first definition appears here
line 9 of file:/home/scherrer/tmp/PL_008f/a.xsd
Failed to parse a schema.
I know TFoo is defined twice, and that's why I have the external binding to solve the conflict.
Obs. both schemas are fictitious, written to exemplify the problem, the real ones (many) are provided by a third party and I can't change them.
Can anyone tell me if this is some kind of xjc restriction (it's not listed here) or shouldn't work at all? Or maybe a bug?
Thanks in advance.
Having 2 different schema documents defining the same name space (and even worse - same element) is equivalent to having 2 different jars contain the same package and same class(es) in the package. This isn't a limitation of jaxb per se - it is a violation of what schema name spaces mean.
In short, you cannot process these schemas together.
The generator cannot create classes because it does not know what to reference. The failure occurs before your attempt to rename. It occurs when reading the schemas.
What you could do is process the schemas separately and change the java package names which are used. This avoids naming conflict in the java package space and basically treats the schema docs as completely separate entities with no references to each other. This can be done by defining the package name to use in the binding:
<jxb:bindings
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
version="2.1">
<jxb:bindings schemaLocation="a.xsd" node="/xs:schema">
<jxb:schemaBindings>
<jxb:package name="com.foo.a"></jxb:package>
</jxb:schemaBindings>
</jxb:bindings>
</jxb:bindings>
I think you found a limitation of data binding. Try data projection instead (Disclosure: I'm affiliated with that project).
Your schema b.xsd looks just like an extension to the a.xsd. You can create a projection interface suitable for b.xsd and use it with any documents that fit either a.xsd or b.xsd.

jaxb override package of a specific generated set of classes

I have a large third party xsd file that pulls in a whole bunch of other xsd files through imports. The whole thing generates over 1000 classes. When I tell the xjc (jaxb) processor to generate everything in a specific package I get all kinds of naming conflicts. If I don't specify a package, then the processor creates java packages using the target attributes in the xsd files, and the whole thing generates without any errors.
The problem is that the package structure is awful because the target names are chosen really poorly. Other developers hate it. They only need a few classes.
So what I've been trying to do is to give the processor a bindings.xml file where I want to specify certain classes to be generated in a given package name.
I've gone back and forth between documentation on Oracle's site, forums, samples. I can't quote every single iteration of my bindings file. My current incarnation is this:
<jaxb:bindings
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
version="2.1"
schemaLocation="heavy.xsd"
node="//xsd:element[#name='Error']"
>
<jaxb:bindings node="//xsd:element[#name='Error']">
<jaxb:package name="ABC"/>
</jaxb:bindings>
<jaxb:globalBindings
underscoreBinding="asCharInWord"
localScoping="toplevel"
typesafeEnumMaxMembers="10000"
generateElementClass="true"
>
</jaxb:globalBindings>
<!--
<jaxb:package name="ABC"/>
-->
<!--
<jaxb:schemaBindings>
<jaxb:package name="ABC"/>
</jaxb:schemaBindings>
-->
<!--
<jaxb:schemaBindings>
<jaxb:package name="ABC"/>
<jaxb:nameXmlTransform>
<jaxb:elementName prefix="Error"/>
</jaxb:nameXmlTransform>
</jaxb:schemaBindings>
-->
</jaxb:bindings>
No matter what I try, I have not yet seen it generate any classes in the ABC package. In this case I want Error to get generated in ABC. Any help would be greatly appreciated.
Unfortunately it is not possible to do what you want. I want the same thing and I'm in the same boat. But straight from Oracles mouth:
http://docs.oracle.com/cd/E19316-01/819-3669/bnbbt/index.html
Relevant Info:
name - is the name of the derived Java interface. It must be a legal Java interface name and must not contain a package prefix. The package prefix is inherited from the current value of package.
So there is simply no way on the element to specify a different package its inherited per xsd.
The way I would do it is more like this:
<?xml version="1.0" encoding="utf-8"?>
<jxb:bindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.1" jxb:extensionBindingPrefixes="xjc">
<jxb:bindings schemaLocation="XSD1.xsd" node="/xs:schema">
<jxb:globalBindings>
<!-- -->
</jxb:globalBindings>
<jxb:schemaBindings xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc">
<jxb:package name="com.something">
</jxb:package>
</jxb:schemaBindings>
<jxb:bindings node="//xs:element[#name='Error']">
<jxb:class xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" name="MyError"/>
<jxb:property xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" name="Whatever"/>
</jxb:bindings>
</jxb:bindings>
<jxb:bindings schemaLocation="XSD2.xsd" node="/xs:schema">
<jxb:schemaBindings xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc">
<jxb:package name="com.somethingelse">
</jxb:package>
</jxb:schemaBindings>
</jxb:bindings>
</jxb:bindings>
Here is an example of bindings.xjb file where java source is generated in primer.myPo package.
<jxb:bindings version="1.0"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jxb:bindings schemaLocation="po.xsd" node="/xs:schema">
<jxb:globalBindings
fixedAttributeAsConstantProperty="false"
collectionType="java.util.Vector"
typesafeEnumBase="xs:NCName"
choiceContentProperty="false"
typesafeEnumMemberName="generateError"
enableFailFastCheck="false"
generateIsSetMethod="false"
underscoreBinding="asCharInWord"/>
<jxb:schemaBindings>
<jxb:package name="primer.myPo">
<jxb:javadoc><![CDATA[<body>Package level documentation for generated package primer.myPo.</body>]]>
</jxb:javadoc>
</jxb:package>
<jxb:nameXmlTransform>
<jxb:elementName suffix="Element"/>
</jxb:nameXmlTransform>
</jxb:schemaBindings>
<jxb:bindings node="//xs:complexType[#name='PurchaseOrderType']">
<jxb:class name="POType">
<jxb:javadoc>A <b>Purchase Order</b> consists of addresses and items.</jxb:javadoc>
</jxb:class>
</jxb:bindings>
<jxb:bindings node="//xs:complexType[#name='USAddress']">
<jxb:class>
<jxb:javadoc><![CDATA[First line of documentation for a <b>USAddress</b>.]]></jxb:javadoc>
</jxb:class>
<jxb:bindings node=".//xs:element[#name='name']">
<jxb:property name="toName"/>
</jxb:bindings>
<jxb:bindings node=".//xs:element[#name='zip']">
<jxb:property name="zipCode"/>
</jxb:bindings>
</jxb:bindings> <!-- node="//xs:complexType[#name='USAddress']" -->
<jxb:bindings node="//xs:complexType[#name='Items']">
<jxb:bindings node=".//xs:element[#name='item']//xs:element[#name='quantity']">
<jxb:property generateIsSetMethod="true"/>
<jxb:bindings node="./xs:simpleType">
<jxb:javaType name="short"
parseMethod="javax.xml.bind.DatatypeConverter.parseShort"
printMethod="javax.xml.bind.DatatypeConverter.printShort" />
</jxb:bindings>
</jxb:bindings> <!-- node="//xs:complexType[#name='Items']" -->
<jxb:bindings node=".//xs:element[#name='USPrice']">
<jxb:property name="Price"/>
</jxb:bindings>
<jxb:bindings node=".//xs:attribute[#name='partNum']">
<jxb:property name="partNumber"/>
</jxb:bindings>
</jxb:bindings>
<jxb:bindings node="//xs:simpleType[#name='USState']">
<jxb:typesafeEnumClass/>
</jxb:bindings>
<jxb:bindings node="//xs:simpleType[#name='ZipCodeType']">
<jxb:javaType name="int"
parseMethod="javax.xml.bind.DatatypeConverter.parseInt"
printMethod="javax.xml.bind.DatatypeConverter.printInt"/>
</jxb:bindings>
</jxb:bindings> <!-- schemaLocation="po.xsd" node="/xs:schema" -->
</jxb:bindings>

How do I create JAXB bindings for docbook

When I run xjc against docbook.xsd, I get a lot of errors:
parsing a schema...
[ERROR] Property "Revision" is already defined. Use <jaxb:property> to resolve this conflict.
line 5965 of file:/C:/log/11/04/20/docbook-4.5/dbpoolx.xsd
[ERROR] The following location is relevant to the above error
line 521 of file:/C:/log/11/04/20/docbook-4.5/dbpoolx.xsd
[ERROR] Element "seealsoie" shows up in more than one properties.
line 1737 of file:/C:/log/11/04/20/docbook-4.5/dbhierx.xsd
[ERROR] The following location is relevant to the above error
line 1733 of file:/C:/log/11/04/20/docbook-4.5/dbhierx.xsd
[ERROR] Element "imageobjectco" shows up in more than one properties.
line 3526 of file:/C:/log/11/04/20/docbook-4.5/dbpoolx.xsd
[ERROR] The following location is relevant to the above error
line 3525 of file:/C:/log/11/04/20/docbook-4.5/dbpoolx.xsd
....etc.
I've tried this with docbook version 4.5 and version 5.0, but with the same result.
Any pointers would be apreciated.
Thanks.
You could use the following bindings file with the DocBook version 5 XML Schema:
binding.xml
<jxb:bindings
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jxb:extensionBindingPrefixes="xjc"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
xmlns:docbook="http://docbook.org/ns/docbook"
version="2.1">
<jxb:globalBindings>
<xjc:simple />
</jxb:globalBindings>
<jxb:bindings schemaLocation="docbook.xsd">
<jxb:bindings node="//xs:attributeGroup[#name='db.common.attributes']/xs:attribute[#name='version']">
<jxb:property name="commonVersion"/>
</jxb:bindings>
<jxb:bindings node="//xs:attributeGroup[#name='db.common.attributes']/xs:attribute[#name='revision']">
<jxb:property name="commonRevision"/>
</jxb:bindings>
<jxb:bindings node="//xs:attributeGroup[#name='db.common.attributes']/xs:attribute[#ref='xml:lang']">
<jxb:property name="xmlLang"/>
</jxb:bindings>
<jxb:bindings node="//xs:attributeGroup[#name='db.common.linking.attributes']/xs:attribute[#ref='xlink:role']">
<jxb:property name="xlinkRole"/>
</jxb:bindings>
<jxb:bindings node="//xs:attributeGroup[#name='db.common.linking.attributes']/xs:attribute[#ref='xlink:type']">
<jxb:property name="xlinkType"/>
</jxb:bindings>
<jxb:bindings node="//xs:attributeGroup[#name='db.common.linking.attributes']/xs:attribute[#ref='xlink:title']">
<jxb:property name="xlinkTitle"/>
</jxb:bindings>
<jxb:bindings node="//xs:element[#name='table']/xs:complexType/xs:attribute[#name='title']">
<jxb:property name="titleAttribute"/>
</jxb:bindings>
</jxb:bindings>
</jxb:bindings>
The command line to include the bindings is:
xjc -extension -d out -b binding.xml docbook.xsd

How do I rename top level Classname during JAXB code generation using XJC?

I am trying to generate some beans from several xsd's. Unfortunately they all have the same root element. I have successfully created a xjc bindings file for renaming sub-elements but cannot find a way to select the root node to change that.
I tried the following but get the error: [ERROR] XPath evaluation of "/" needs to result in an element.
<jxb:bindings version="1.0" 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" xmlns:com.fnf="http://www.fnf.com/xes">
<jxb:bindings schemaLocation="transcode-submit.xsd" node="/xs:schema">
<jxb:bindings node="/">
<jxb:property name="Newname"/>
</jxb:bindings>
</jxb:bindings>
I figured it out.
<jxb:bindings version="1.0" 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" xmlns:com.fnf="http://www.fnf.com/xes">
<jxb:bindings schemaLocation="transcode-submit.xsd" node="/xs:schema">
<jxb:bindings node="//xs:element[#name='OLDROOTNAME']">
<jxb:class name="NEWNAME"/>
</jxb:bindings>

Categories