Correct way to unmarshal empty strings as null with JAXB

I need to work with large XML documents that do not properly handle missing attribute data. Rather than just omitting the missing data attribute, the attribute is specified with an empty string value. This causes a problem with unmarshalling as the empty string is a value.

For example what should be

<SOME_ELEMENT attr1="someValue"/>


Instead of this

<SOME_ELEMENT attr1="someValue" attr2="" attr3=""/>


I'm trying to come up with a "correct" way to gracefully handle this malformed XML. The goal is to treat an attribute as if it were omitted when the attribute value is an empty string and the empty string is never a valid value for that attribute (e.g. integers).

I am currently using XMLAdapters to translate these empty strings to zero (as suggested in this post ), but this seems to be the wrong solution. Many of the attributes in the docs that I work already use type adapters shared from other code, and there doesn't seem to be a way to specify more than one XMLAdapter for an attribute.

Is there a standard way to handle a situation like this that I just missed?



I'm looking for a solution that doesn't require me to edit each of the JAXB distributed classes, as there are several dozen of them all with the same needs. Ideally, a solution to this problem would allow me to specify a common policy for all attributes and, if necessary, allow certain overrides.


source to share

2 answers

Since this has been inactive for a while, I might as well answer the question where we left off on it.

It looks like Skaffman's answer to JAXB: how to get JAXB NOT to unbind the empty string to 0 in the link in the description is the best option in the end.



I think the pattern you want to follow is that in this post: Configuring JAXB unmarshall process error handling

With an XML element can indicate that it is zero (as follows). With string types, empty elements and attributes (and sometimes missing elements) can be interpreted as empty strings. Thus, you should treat your logic as business logic that is handled with the afterUnmarshal event.

<foo xsi:nil="true" />




All Articles