jackson-dataformat-xml icon indicating copy to clipboard operation
jackson-dataformat-xml copied to clipboard

Improve support for XML lists via `JsonNode`

Open ofrias opened this issue 1 year ago • 4 comments

Hello. I understand that Jackson 3 plans to better support formats other than JSON. In particular, for XML, it would be nice to have a method like JsonNode.getArray(String element) to get XML node lists in ArrayNode format automatically, even for 1 element lists which are currenty returned by JsonNode.get("element") as an ObjectNode. For more context please see this SO question. Thanks!

ofrias avatar Dec 17 '24 15:12 ofrias

Thank you for your suggestion. We can consider something like this (getAsArray() perhaps). But it cannot quite be XML-specific, altho this could be generally useful across data formats.

cowtowncoder avatar Dec 17 '24 20:12 cowtowncoder

Created https://github.com/FasterXML/jackson-databind/issues/4868 as follow-up

cowtowncoder avatar Dec 27 '24 02:12 cowtowncoder

... and closed that issue. There are reason it is not practical to do.

I'll re-open this issue however.

cowtowncoder avatar Feb 13 '25 17:02 cowtowncoder

Since the other issue is closed, I add here my reasoning.

With the current implementation, JsonNode.get("element") returns an ArrayNode for this XML:

    <list>
        <element>
            <a>value 1a</a>
            <b>value 1b</b>
        </element>
        <element>
            <a>value 2a</a>
            <b>value 2b</b>
        </element>
    </list>

but an ObjectNode for this XML:

    <list>
        <element>
            <a>value a</a>
            <b>value b</b>
        </element>
    </list>

But both XML are have in fact the exact same structure, the only difference is the number of elements in the list.

My proposal is to add to JsonNode a method asArray(String element) returning an ArrayNode for both cases.

Since JsonNode does not contain a reference to the JsonNodeFactory, it could just implement a empty method throwing an Exception (like many other methods in the class). The implementation will be in ObjectNode and could be something similar to:

    public JsonNode asArray(String element) {
        JsonNode node = get(element);
        if (node == null) {
            return this._nodeFactory.arrayNode();
        }
        if (node.isArray()) {
            return node;
        } else {
            return this._nodeFactory.arrayNode().add(node);
        }
    }

ofrias avatar Feb 13 '25 18:02 ofrias