Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handling XMLElement nillable like JAXB #89

Closed
5kilodope opened this issue Jan 9, 2014 · 10 comments
Closed

Handling XMLElement nillable like JAXB #89

5kilodope opened this issue Jan 9, 2014 · 10 comments

Comments

@5kilodope
Copy link

I cant find any way to make Jackson serialize the typical "xsi:nil"-Attribute that is defacto standard to represent NULL-Values in XML? Please correct me if i see this wrong ;-)

In JAXB this can be done easily by annotating a java-variable with: @xmlelement(nillable=true)

see also: http://blog.bdoughan.com/2012/04/binding-to-json-xml-handling-null.html

can/should Jackson do this?


here also a compare of JAXB and Jackson.

  • jackson serializes NULL-values per default as
    • can be configured so NULL-values will not be serialized at all
  • jackson deserializes missing elements as NULL
  • jackson deserializes and for branch-nodes as NULL
  • jackson deserializes and for leaf-nodes as NULL..
    but as soon as attributes (z.b. xsi:nil) are on the leaf-node, jackson
    seems to think its a branch-node instead and throws an exception
    while mapping it to an pojo
  • JAXB does not serialize NULL-values per default
    • If fields are annotated with @nillable, the field will be serialized as <x xsi:nil="true/>
  • JAXB deserializes missing elements as NULL
    • If fields are annotated with @nillable, will be deserialized as NULL
  • JAXB deserializes or for branch-nodes by providing default-values for all contained
    leaf-nodes.
  • JAXB deserializes or for leaf-nodes not as NULL-values but provides default-values (an integer will be 0 by default).

so it seems to me that the best way at the moment is not to serialize/deserialize NULL-values but just leave them out. The only bad thing about this is, that empty strings "" can not be represented...

@cowtowncoder
Copy link
Member

Actually whether nulls are serialized or not depends on general Jackson settings, and this handling is not XML specific. There are couple of ways;

  • Use @JsonInclude annotation to include inclusion (or not) of nulls on per-type basis
  • Use ObjectMapper.setSerializationInclusion(...) to indicate default value in absence of annotations.

So parts of handling that deal with simple omission of nulls (for serialization) exist.

But question of using xsi:nil is still valid, and I am open to suggestions. The only (?) tricky part is the question of how to handle namespace, but underlying Stax implementation should be able to handle that dynamically (albeit with potential extra ns declarations).

I think it would make sense to allow old behavior (empty String) as well, so perhaps a new XML-specific feature is in order here.

Question of handling input is interesting as well; it would make sense to recognize special value of "nil", but it is bit tricky... since we may not have enough context to do this reliably -- we do not want to accidentally convert textual "nil" String into Java null.

This issue is something that would make sense to discuss on Jackson user or dev list; I think other users of XML module may have opinion on what kinds of changes would make most sense.

@5kilodope
Copy link
Author

@cowtowncoder

thanks for feedback.

we implemented our solution with jackson and without using "xsi:nil". The only bad thing is, that therefore we cannot differ between empty strings and null-values. But we try to cope with that, because normally there should be no reason to use empty strings instead of null-values.

yes i forgot to mention namespace for xsi:nil.
As far as i know, the namespace can be defined on different elements and can be used in subelements (?). Example for declaration:
<item xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />

@cowtowncoder
Copy link
Member

Correct, namespaces can be declared higher up the hierarchy, but the problem is that streaming generator has no access to anything higher. Conversely, users tend to dislike extra declarations above, if they don't need them.

But... either way shouldn't be a big deal: either there are extra declarations; or, we force binding for root element (but only when feature is enabled). So it's just a minor annoyance at worst I think.
I am thinking that pre-declaring this might still be the right thing to do.

@5kilodope
Copy link
Author

Hi,

just wanted to note some things i found out....

  • xsi:nil is the official representation for NULL-Values with XML-Schema-Standard.
    (see: http://www.w3.org/TR/xmlschema-1/#xsi_nil), so if you open up this one, you should think about jackson supporting xml-schema (xsd) as well?

Incoming values can have three states:

  • not defined
  • null
  • value

In JSON this is possible, because json already differs between these 3 states. Lets say we expect three variables in a json-object (test1,test2,test3) because we have defined them in our annotated JAVA-Pojo. And we get an incoming json-object that we want to map to this JAVA-Pojo:

{
  "test1" : null,
  "test2": : "value"
}

Lets see... we got "test1" as NULL and we got "test2" as "value" and we got "test3" as undefined...

The same with Jackson-XML is not possible at the moment, because there is no real (standard-compliant) representation for NULL. You defined more or less your own standard that says empty xml-element means null?

Just some thoughts from me to this topic.

Interoperability with JAXB at the moment is problematic, because if we generate XML with Jackson and want to read this XML with JAXB, JAXB cannot recognize <x/> or <x></x> as NULL in any way. JAXB will use default-values ("" for Strings, 0 for Integer...)...

I will look at others like JiBX to see how they do this...

you wrote:

"...But... either way shouldn't be a big deal: either there are extra declarations; or, we force binding for root element (but only when feature is enabled). So it's just a minor annoyance at worst I think..."

This should be ok 👍
Would be cool if JAXB can read the XML that has been generated with Jackson and if Jackson can read XML that has been generated by JAXB 💃

@cowtowncoder
Copy link
Member

I fully agree in that inter-operability is important, and we will try to get things as close as possible.

As to XML Schema, there are no plans to make use of XML Schema directly. Tools exist in JAXB suite to generate various things; and due to complexity of XML Schema I just don't think we want to go down that rat hole.

This is not to say we could not add features that are related to schema -- for example, Stax parsers allow validation of content in streaming fashion against DTDs, XML Schemas, and RelaxNG schemas. Ability to enable validation via external tools (XML module relies on Stax lib for actual parsing and generation) could be something we'd support, just as an example.

@5kilodope
Copy link
Author

thanks for info. I will wait now until its done ;-)

I have also tried to find a workaround that can be used until xsi:nil support
in jackson is ready. For info:

See: http://stackoverflow.com/questions/21002930/jackson-xml-binding-handling-null-vs-empty-string

@antidote2
Copy link

antidote2 commented Apr 22, 2016

+1 as I wish to stick to standards, and this forces me to configure FasterXML

@javier-langle
Copy link

Hi, I am facing same issue as above, receiving <MyElement ns:nil="true/> (ns is a namespace defined at the root level). I don't have any control over the xml, my app consumes it from a vendor.
Is this feature now supported? If so, could you please tell me the version?
Thanks

@cowtowncoder
Copy link
Member

I will actually create a new issue for adding support for mapping xsi:nil attribute valued elements into JsonToken.VALUE_NULL, and close existing issues as they tend to cover wider scope (like here).

@cowtowncoder
Copy link
Member

Close in favor of #354

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants