Skip to content

Naive attempt at fixing #306 #754

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

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.

@@ -208,6 +209,10 @@ public PropertyName findNameForDeserialization(MapperConfig<?> config, Annotated
PropertyName pn = PropertyName.merge(_findXmlName(a),
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?

@@ -68,7 +68,7 @@ public String extractScalarFromObject(JsonParser p, ValueDeserializer<?> deser,
final String propName = p.currentName();
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.

!_cfgIntrospectorConfig.inferXmlTextPropertyName()) {
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(...)).

@@ -43,7 +44,7 @@ public void testMixedContent() throws Exception
{
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.

@@ -19,23 +20,23 @@ public class JsonNodeMixedContent403Test extends XmlTestUtil
public void testMixedContentBefore() throws Exception
{
// 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