Skip to content

Conversation

duoduobingbing
Copy link
Contributor

This PR aims to fix #306 naively by just changing the default property name of XmlText from "" to <xml:text>. The new value was chosen, because it is an invalid property and element name in XML and thus should hopefully not collide with existing setups.

I was not sure if XmlText having the property name "" is considered an implementation detail. If it is not an implementation detail this is most likely to be considered as a breaking change.

Feel free to close this PR if e.g. something else is planned to fix #306 or if XmlText has to keep the property name empty string because of compatibility reasons.

@cowtowncoder
Copy link
Member

Choice of "" to represent XmlText is not a simple implementation detail so I doubt we can change that for Jackson 2.x, unfortunately due to (like you correctly guessed) compatibility concerns.

But I think we might be able to do just that for 3.x, being major version change.

I haven't looked into PR yet (just description) to comment on changes, but wanted to point out that change as described likely can't be made in 2.x branch.

@cowtowncoder
Copy link
Member

Ok so I do like the idea -- just need to re-create for 3.0.0 (branch 3.x).

@duoduobingbing duoduobingbing changed the base branch from 2.x to 3.x April 28, 2025 17:46
@duoduobingbing duoduobingbing force-pushed the feature/record-with-jacksonxmltext branch from 24b57f1 to c53bc27 Compare April 28, 2025 19:00
@duoduobingbing
Copy link
Contributor Author

Ok so I do like the idea -- just need to re-create for 3.0.0 (branch 3.x).

Thanks for looking into this so swiftly.

I did rebase onto 3.x and just used FromXmlParser.DEFAULT_TEXT_PROPERTY and removed the newly introduced XmlTextPropertyNameHolder.PROPERTY_NAME completely.

super.findNameForDeserialization(config, a));
if (pn == null) {
if(_hasAnnotation(a, JacksonXmlText.class)){
return PropertyName.construct(FromXmlParser.DEFAULT_TEXT_PROPERTY);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quick notes: not just _hasAnnotation -- JacksonXmlText.value() must be true (specifying false can be used to disable annotation's effect).

But I have related concern: there now won't be a way to override name of logical property to use as it's effectively hard-coded. Should there be a way to re-configure that? And if so, how?
(MapperConfig passed won't have access to XML-specific config mapper has. But maybe this introspector should have its own config or something.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the first note: This has been fixed in the latest commit of this pull request

For the second note: I've added a config on the introspector so that this can be configured.

@cowtowncoder cowtowncoder added the cla-received PR already covered by CLA (optional label) label May 10, 2025
@cowtowncoder
Copy link
Member

Ok. I am not quite sure what the added configurability does, to be honest. I know I asked for it, but the combination of name and "infer" flag is bit unclear to me.

I realized that FromXmlParser already allows specifying different underlying name to use like so

FromXmlFactory f = FromXmlFactory.builder()
    .nameForTextElement("text-marker-element")
    .build();

So, f.ex input like:

<root attr="123">456</root>

would in 3.0 be exposed as:

{
  "root": {
    "attr": "123",
    "<xml:text>": "456"
  }
}

with default settings.

Given this, I wonder if annotation-level configurability is really needed? If it is, how does it control things?

JsonToken t = p.nextToken();
if (t == JsonToken.VALUE_STRING) {
if (propName.equals("")) {
if (FromXmlParser.DEFAULT_TEXT_PROPERTY.equals(propName)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this needs to actually consider FromXmlParser._cfgNameForTextElement, since that may be configured different from default. Comment above hints at that.

Will change to do that.

return _cfgIntrospectorConfig.xmlTextPropertyName();
}

if (_hasOneOf(a, ANNOTATIONS_TO_INFER_XML_PROP)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will look for @JacksonXmlText OR @JacksonXmlElementWrapper and handling will now differ -- former should use configured "text element name", latter should not (should return "use default").

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not quite understand, the highlighted line only looks for @JacksonXmlText

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I meant line 225 right after (if (_hasOneOf(...)).

JsonNode fromXml = XML_MAPPER.readTree("<root>first<a>123</a>second<b>abc</b>last</root>");
final ObjectNode exp = XML_MAPPER.createObjectNode();
exp.putArray("")
exp.putArray(FromXmlParser.DEFAULT_TEXT_PROPERTY)
Copy link
Member

@cowtowncoder cowtowncoder May 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ohhhhhhh. This is NOT good -- what used to be something like:

{
  "":["first","second","last"],
  "a":"123",
  "b":"abc"
}

now looks like:

{
  "<xml:text>":["first","second","last"],
  "a":"123",
  "b":"abc"
}

which I don't think is what anyone likes to see :-(

So for JsonNode at least exposing XML character data sections should be with nominal key of "".
And I don't think it is reasonable to expected those using XmlMapper.readTree() to have explicitly configure things to work this way.

We need to figure out another way to handle the issue, I think.

Copy link
Contributor Author

@duoduobingbing duoduobingbing May 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to figure out another way to handle the issue, I think.

I mean this PR was just a naive shot at solving #306 by changing the property name, if it has to be "" I'm fine with closing this PR - because I do not know how to make it so, that the property name differs from the nominal key.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. I'll leave this open because I'd really like to figure out a way and feel there probably is a way (despite not seeing it yet). :)

I appreciate your attempt; sorry it took me a while to sync up to what changes really mean.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No Problem, thanks for having a look at it. I will close this for now. Feel free to reopen or use the code in any way, shape or form you see fit.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. Thank you for your help here @duoduobingbing .

{
// First, before elements:
assertEquals(JSON_MAPPER.readTree(a2q("{'':'before','a':'1','b':'2'}")),
assertEquals(JSON_MAPPER.readTree(a2q(String.format("{'%s':'before','a':'1','b':'2'}", FromXmlParser.DEFAULT_TEXT_PROPERTY))),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and same here obviously.

@duoduobingbing duoduobingbing deleted the feature/record-with-jacksonxmltext branch May 14, 2025 06:50
@duoduobingbing duoduobingbing restored the feature/record-with-jacksonxmltext branch May 14, 2025 06:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-received PR already covered by CLA (optional label)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Can not use @JacksonXmlText for Creator property (creator parameter)

2 participants