These Corporate Clean Comedians Are the Best of the Best

At least these days they are. But never fear, that’s why we’re here! Together, we’ve compiled a list of the best of the best in the corporate clean comedy business. Why? So you don’t have to spend…

Smartphone

独家优惠奖金 100% 高达 1 BTC + 180 免费旋转




Schema Namespace Designs

JAXB library is very useful as it allows to generate the JAVA Object representation (POJOs) of the XML Schema definition and use such objects during the marshalling and unmarshalling process (transforming POJO object into the XML document and in the opposite direction).

Nevertheless, there are situations in which JAXB is not dealing properly with the XSD files and as a result multiple duplicated POJO objects are generated. Obviously, such duplication of code is undesirable as the code that is using it becomes a nightmare. Certainly the Chameleon Namespace Design for XML schema files that is consumed by JAXB is example of that.

Before presenting the solution to this problem I will briefly describe several different approaches that could be used for the XML schema namespace design and show how the JAXB generator (XJC) is dealing with them. I believe this will allow to fully understand the problem.

Here are the three design approaches:

You will find a great article about that here:

To make everything clear and simple I’ve decided to use the example XSD files from the article above.

More specifically we will use the following XML schema definitions: Product.xsd, Person.xsd and Company.xsd which is composed of the previous ProductType and PersonType elements.

This is one of the most popular schema designs. Each definition file has different XML namespace defined:

As You can see the Product.xsd has http://www.product.org, Person.xsd — http://www.person.org and the Company.xsd has the http://www.company.org namespace.

Heterogenous Namespace Design

The Product.xsd and Person.xsd are imported in the company schema definition file. What is more there is a need to define prefixes for them (per and pro) in order to refer to them from the company definition.

This is also pretty popular schema design and it seems it is the easiest one. Each definition file has exactly the same XML namespace defined (http://www.company.org):

Homogenous Namespace Design

As You can see there is no need to use any prefixes. Person and product elements directly refer to the PersonType and ProductType.

Finally in the chameleon namespace design there is no target namespace defined in the Product.xsd and Person.xsd schema files:

Chameleon Namespace Design

When these product and person definitions are included in the company schema definition (Company.xsd) the elements defined in the Product.xsd and Person.xsd schema files obtain the target namespace defined in the company schema (http://www.company.org) — like chameleon. To be honest it is a pretty smart design as it allows to reuse the common definitions in the XSD files with different target namespace defined. What is more there is no need to specify the namespace for them (the common definitions) and use any prefixes.

Now lets’ see how JAXB deals with these all 3 designs.
Before we continue we have to extend our simple example with the additional schema file in order to show You what is exactly the problem when using JAXB with chameleon approach.
The new Division.xsd definition is very similar to Company.xsd — the only difference is the element name — Division and the target namespace — (http://www.company.org/division for heterogenous and chameleon design). Apart from this the other parts related to the imported/included product and person definitions stay the same.

Division

Let’s see what objects are going to be generated by JAXB for the heterogenous design. Each object resides in the separate package and JAXB assumes by default that each java package has its own unique namespace defined. The information about the package could reside in the annotations inside the each POJO object or in the package-info.java file (by default) per package. This is controlled by JAXB XJC generator (-npa option).

By contrast, in the homogenous approach we have only single package and single namespace defined.

Homogenous Namespace Design in JAXB

A bit different situation is in the chameleon design — there are only 2 packages — division and company and the elements that were defined in the schema files with no target namespace defined are duplicated. These classes (PersonType and ProductType) are identical in the both packages as their definition comes from the same schema file. Unfortunately JAXB generates separate JAXB objects for each namespace even if their definition is exactly the same.

This technique allows JAXB generator to reuse the schema definitions. In order to achieve it we need to define temporary namespaces for the types with no target namespace defined:

JAXB bindings allows us to instruct the JAXB generator to reuse the problematic types in all generated java packages.

In our simple example there are only 2 elements defined (ProductType and PersonType) but in practice we will probably have to deal with many more XML definitions.

Do not worry, we can automatize this step with XJC in the following way (for example using gradle task):

Therefore here is our final bindings file:

Finally we can generate the JAXB classes:

The JAXB objects should be properly generated in the generated folder.

You will probably notice that the object representation looks like that for heterogenous namespace design:

Yes, that’s exactly what we are doing — we are emulating heterogenous namespace design for the chameleon schema files !

Now, we have to get rid of our proxy namespaces to return back to the original (chameleon) schema. More specifically, we have to remove namespace attribute from the package-info.java file for both org.product and org.person packages.

package-info.java files before modification
package-info.java files after modification

Finally we can marshal and unmarshal our XML documents using the Default Namespace Remapping technique:

1. Define the default namespace for the types with no namespace:

2. Perform marshalling/unmarshalling as usual

Here’s the code that is responsible for that (JDK 1.8):

and the example XML file that is used for our test:

That’s it for now !

I hope You find it useful.

Add a comment

Related posts:

Entre um ritmo e outro.

Ora Ella vive pecando pelos exageros. Sem filtros, não mede o tom da voz em meio a tanta euforia e extravasa entre risos e gestos, Ella ri até chorar e chora até rir. Dessas habilidades só quem…

Story about you having to go pee really bad

It is a beautiful summer day, one of those ones with a clear blue sky only touched by biplanes buzzing through the air, reassuring sky writing trailing behind. Naturally, you decided to go for a walk…

Moral Posturing and Meaningful Change in the Internet Age

Six months into 2020, hope for the new decade has all but withered away. In January, the United States tried to juggle the Israel-Palestine conflict with a messy impeachment trial, all the while…