Reputation: 606
I am using JAXB Maven plugin in Intellij-IDEA (org.codehaus.mojo:jaxb2-maven-plugin:1.6) to generate a given xsd file to objects. The xsd is pretty large and contains many types, most of which are optional.
Right now when I unmarshal an XML to objects, missing elements are represented as null objects.
So for example, if I am trying to do rootObject.getAccount().getAccountName()
but the Account element is missing altogether from the XML, I get a NullPointerException
I would like to configure JAXB to unmarshal the full object tree to include those representing missing elements.
Is this possible?
Upvotes: 3
Views: 1465
Reputation: 43661
This would be actually incorrect, as null
property is semantically different from this property stubbed with some default value. So setting some new Account()
to account
property for a missing value would not be correct.
If you want to simplify your code, consider using JAXB2 Fluent API plugin. You'll be probably able get code like:
rootObject.withAccount().getAccountName()
(Implicitly initializes account
.) I am not 100% sure if it will work that way, but definitely worth giving it a try.
Update
A few notes on your comments.
I looked at the link you've posted and tried to look it up online but if I understand correctly, it is mostly used for populating values in the objects rather than reading them. The link you sent says: The FluentApi plugin provides Method Chaining for bean setters. I was looking for a way to somehow avoid checking for nulls when trying to access nested classes.
You are correct. However you said specifically "unmarshal the full object tree to include those representing missing elements". My point is, it would be incorrect for JAXB to fill in these missing properties, but you can do this and the Fluent API plugin is the closes I would know to an easy-to-use API for this case. But this does not answer your question as, probably, there is no answer at the moment.
The comments there mostly suggest to either suck it up and check for null values along the way, use reflection, or just catch the error. I ended up going with the first option for performance considerations.
Probably the best thing you can do at the moment. This is what I do (checking for null
s) all the time. Well, not quite nice, but also quite trivial.
Next, I though a bit on how could this be solved at all?
XJC supports plugins which can augment the generated code. This is a very powerful tool, I did a great lot with these plugins. But what code should be generated? How should it look like in Java?
Filling properties with default values is simply not correct. I think gooing this way will not lead to good results.
Something like rootObject.getAccount().getAccountName()
won't work due to null
s. So how would it look like in Java?
The best thing that came to my mind is a interface like getValueByPath(String propertyPath)
so that you could do something like:
rootObject.getValueByPath(`account.accountName`);
The getValueByPath(String path)
could be generated by a plugin. It is possible to generate code which would resolve such path
s without any reflection. The generated code would check for own properties and either return the target value, or call getValueByPath(...)
on it or return null
if not found/null
.
But then you won't have autocompletion and the whole thing would be much more error prone.
Upvotes: 2