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

Support use of xsi:type for polymorphic serialization (ToXmlGenerator.Feature.AUTO_DETECT_XSI_TYPE) #324

Closed
philipzhaoTS opened this issue Dec 13, 2018 · 7 comments
Labels
2.17 Issues planned at earliest for 2.17

Comments

@philipzhaoTS
Copy link

philipzhaoTS commented Dec 13, 2018

Hey,

I have two subclasses like the following:

public abstract class Foo{}
public class Foo1 extends Foo {}
public class Foo2 extends Foo {}

And I want to generate XML as the following:

<Foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Foo1"></Foo>
<Foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Foo2"></Foo>

Notice there is xsi:type field in the XML.

In JAXB, I could do:
JAXBContext.newInstance(Foo.class, Foo1.class, Foo2.class);
Which will provide the xsi:type tag.

How would I do this in Jackson?
Many thanks

@cowtowncoder
Copy link
Member

With Jackson you would need to use @JsonTypeInfo in base class, although unfortunately that would not allow use of namespace URI (other than default "no namespace", i.e. no prefix).

@vetler
Copy link

vetler commented Oct 3, 2019

There's currently no way to do this out of the box.
You might try something like @JsonTypeInfo(use = JsonTypeInfo.Id.CUSTOM, property = "xsi:type"), but there are two challenges to this;

  1. you would have to write your own type resolver (not such a big deal, annotat with @JsonTypeIdResolver and write a class implementing TypeIdResolverBase

  2. the attribute name xsi:type would be escaped to xsi_type, so you'd get <Foo xsi_type="Foo1"/>

The last problem is a dealbreaker, and it is possible to get around it by jumping through some hoops, but you might be better off just doing string replace on the final XML file.

@cowtowncoder
Copy link
Member

I wonder if one solution here would be addition of base implementation of handled to use with CUSTOM identifier type.

Or, possibly, XML-module-specific annotation to indicate that "type id" should be embedded "as attribute" -- problem being that although we could in theory just add a new Include.As. value the general rule is to avoid format-specific enums and annotations in main jackson-annotations.

But since this module already overrides quite a few pieces of Polymorphic Id handling, it just might be possible to tweak output to be done as attribute. Deserializer would handle it fine, I think, since attribute values are exposed similar to element values, but preceding them (which is actually good for use case).

This would just be part of the problem of course, but it could be the first step.

@cowtowncoder cowtowncoder added 2.12 and removed 2.11 labels May 20, 2020
@cowtowncoder cowtowncoder added 2.13 and removed 2.12 labels Nov 13, 2020
@afranken
Copy link

Is there any update on this?
Any plan to support "xsi:type" for serialization and deserialization in Jackson XML?
A workaround was suggested in comments to this issue, what would that look like?

@cowtowncoder
Copy link
Member

At this point it's a "PRs welcome" -- I would definitely like to add support but do not want enough to time to work on everything and this is not at the top of the pile. But as usual I try hard to make time to help others if and when they try to provide a PR.

Ability to produce namespace might be somewhat doable but likely requires work on jackson-databind to allow for both annotating namespace (for property name used in @JsonTypeInfo) and making sure qualified name (local name and namespace) are passed through. Unfortunately it is not very easy to outline how to do that, I'd have to dig in and... at that point could probably solve it.

Fundamentally, tho, what one needs is a TypeSerializer that can write such qualified/scoped name, instead of simple "local" name.

@cowtowncoder
Copy link
Member

I have an idea of how to make this work, without having to make TypeSerializer etc changes for full namespace-awareness.

How about ToXmlGenerator.Feature like... AUTO_DETECT_XSI_TYPE which would basically recognize "plain" property name of "xsi:type" and internally convert it to case of namespaced-property written as attribute.
Not ideal, but could make output side work; and if coupled with similar FromXmlParser.Feature (to do auto-detection in reverse direction) might allow end-to-end handling as expected.

If so, @JsonTypeInfo(include = As.PROPERTY, property="xsi:type") would work "as expected" for XML, doing automatic conversion.

I hope to have time to play with this to see how feasible it is.

cowtowncoder added a commit that referenced this issue Jan 31, 2024
@cowtowncoder cowtowncoder changed the title How to generate xsi:type for XML output Support use of xsi:type for polymorphic serialization (ToXmlGenerator.Feature.AUTO_DETECT_XSI_TYPE) Jan 31, 2024
@cowtowncoder cowtowncoder added the 2.17 Issues planned at earliest for 2.17 label Jan 31, 2024
@cowtowncoder
Copy link
Member

Implemented via #633: generation-side support enabled with ToXmlGenerator.Feature.AUTO_DETECT_XSI_TYPE; see unit test XsiTypeWriteTest.java for examples.

Will file counterpart for reader side next.

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

No branches or pull requests

4 participants