jackson-dataformat-xml
jackson-dataformat-xml copied to clipboard
How to generate xsi:type for XML output
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
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).
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;
-
you would have to write your own type resolver (not such a big deal, annotat with
@JsonTypeIdResolver
and write a class implementingTypeIdResolverBase
-
the attribute name
xsi:type
would be escaped toxsi_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.
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.
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?
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.