Reputation: 866
I am writing a webservice client using a very large webservice schema (40,000 lines with 5,000 elements). This schema was provided externally, i.e. I can't change it.
I use JAXB to generate Java classes for the client. By default, all classes are generated into a single Java file, which ends up having 500,000 lines.
This is a huge problem for my IDE (Eclipse), which hangs and crashes even with 4GB of memory.
I could overcome this problem by generating separate Java files, but many of the entities in the schema have identical names. There are more than 500 name clashes, when all Java classes are generated in the same package.
If I were to avoid these clashes using jaxb bindings, I would have to manually write over 500 binding definitions.
It would be very convenient if I could automatically map the XML hierarchy into java packages, but I have nevery seen an example for this.
I can't disclose the schema itself, but here is a small example to illustrate the problem:
<xs:element name="top">
<xs:element name="customer">
<xs:element name="name">
...
</xs:element>
<xs:element name="address">
...
</xs:element>
<xs:element name="employee">
<xs:element name="name">
...
</xs:element>
<xs:element name="address">
...
</xs:element>
</xs:element>
</xs:element>
<xs:element name="provider">
<xs:element name="product">
<xs:element name="name">
...
</xs:element>
</xs:element>
<xs:element name="name">
...
</xs:element>
<xs:element name="address">
...
</xs:element>
</xs:element>
</xs:element>
The desired result would be Java classes like:
com.mycompany.generated.Top
com.mycompany.generated.top.Customer
com.mycompany.generated.top.customer.Name
com.mycompany.generated.top.customer.Address
com.mycompany.generated.top.customer.Employee
com.mycompany.generated.top.customer.employee.Name
com.mycompany.generated.top.customer.employee.Address
...
com.mycompany.generated.top.Provider
...
How can I achieve this?
Edit: The original xsd (unlike the snippet provided here) is perfectly valid, but it defines every element individually. E.g. even though there are many types called address with identical definitions, each one is defined between its element tags instead of re-using a type. This is one reason why it's so big, and why there are so many identical classes. To make it even more complicated, I also found type definitions with identical names and different details.
I don't need to fill all elements in the WS, so my main objective is to enable successful code generation without much fuss.
I am reluctant to change the schema locally to re-use type definitions, because I expect future changes from above which would require applying the same modifications again and again.
Upvotes: 0
Views: 470
Reputation: 43699
You can generate separate Java classes with:
<jaxb:globalBindings localScoping="toplevel"/>
But then this still leaves you with 500 class name customizations. You can either go brute-force or write an XJC plugin to handle that. I think brute-force would be faster than writing a plugin.
However I wouldn't disrtibute classes among different packages. JAXB has a number of package-level feature which may fail/go wrong if you distibute classes of the same namespace among different packages. So I'd just do <jaxb:class name="CustomerName"/>
customizations.
I'd also consider writing an XSLT transformation which would generate the bindings file out of the schema automatically. Should not be difficult at all.
Upvotes: 1