JAXB - Install XmlAdapter only for a specific subtype of an element?

I need to generate an xml element that can have any "primitive type" as value (xsd: string, xsd: boolean, etc.). Examples:

<field xsi:type="xsd:string" name="aString">String Value</field> <field xsi:type="xsd:dateTime" name="aDate">2011-10-21</field> <field xsi:type="xsd:dateTime" name="aDateTime">2011-10-21T12:00:00</field> ... 

So, I use this implementation, which forces JAXB to define xsi:type primitive type:

 public class Field { @XmlAttribute private String name; @XmlElement Object value; } 

and it works as expected, but all java.util.Date gets type xs:dateTime ...

Now I want to change the behavior of the marshaller ONLY when the 'value' object is an instance of java.util.Date to get these fields:

 <field xsi:type="xsd:date" name="aDate">2011-10-21</field> <field xsi:type="xsd:dateTime" name="aDateTime">2011-10-21T12:00:00</field> 

So, I am creating an adapter, but if I try this:

 @XmlElement @XmlJavaTypeAdapter(DateAdapter.class) Object value; 

The adapter must handle the java.lang.Object type

 public class DateAdapter extends XmlAdapter<String, Object> {...} 

But I do not want to lose JAXB marshalls for all other objects (Integer, Double, etc.) ...

Is there a way to install an adapter for a specific subtype of an element?

+6
source share
2 answers

I came across a similar situation, although I went from XSD and generated classes from there. However, the solution should also be portable for you.

In my cases, I wanted to expand the use of a simple string in the XSD model so that it displayed as a UUID in Java code, and then another was released as a class in other places, and so on. XML side, whole string (xs: string), so how to get all these strings into separate java side types ...

What I ended up doing, in XSD, I created simple types for each case, here is the UUID declaration:

And use this instead of the required string.

Then I created a binding file where I specified my XmlAdaptors, just like you, but now I have separate goals and, therefore, you can use several adapters specifically designed for each type of "xml".

Now you have additional complexity, since on the Java side, the representation of your field is just an object. I assume you cast it as soon as you recognize the type attribute. It is possible to create a subclass of the field for each case, this will allow you to change the typeADaptor declaration.

0
source

to try

http://jaxb.java.net/guide/Mapping_interfaces.html#Use__XmlJavaTypeAdapter

XmlJavaTypeAdapter for Interfaces with Multiple Implementations

-1
source

Source: https://habr.com/ru/post/900112/


All Articles