Deserialization xml with mixed unwraped array elements
See original GitHub issueI found a bug with deserialization unwrapped arrays.
If xml elements are ordered like:
<root>
<arrayElement/>
<otherProperty/>
<arrayElement/>
</root>
then first <arrayElement/>
is ignored and array contains the second element only.
jackson version: 2.9.3
I wrote the test case (sorry for using Lombok, I wanted to omit boilerplate code and do not write many equals
methods).
POJO definition:
package com.example.xml;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.List;
@JacksonXmlRootElement
@Data
public class Root {
@JacksonXmlProperty(localName = "cat")
@JacksonXmlElementWrapper(useWrapping = false)
public List<Cat> cats;
@JacksonXmlProperty(localName = "dog")
public Dog dogs;
// Nested classes
@Data
@AllArgsConstructor
public static class Dog {
@JacksonXmlProperty(isAttribute = true)
public String name;
}
@Data
@AllArgsConstructor
public static class Cat {
@JacksonXmlProperty(isAttribute = true)
public String name;
}
}
Test class:
package com.example.xml;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import org.junit.Test;
import java.util.ArrayList;
import static org.junit.Assert.assertEquals;
public class DeserializationTest {
@Test
public void contextLoads() throws Exception {
Root actual = xmlMapper()
.readValue(XML, Root.class);
assertEquals(EXPECTED, actual);
}
private static final String XML = "<root>" +
" <cat name=\"first cat\"/>" +
" <dog name=\"first dog\"/>" +
" <cat name=\"second cat\"/>" +
"</root>";
private static final Root EXPECTED = new Root() {{
cats = new ArrayList<Cat>() {{
add(new Cat("first cat"));
add(new Cat("second cat"));
}};
dogs = new Dog("first dog");
}};
private static XmlMapper xmlMapper() {
final XmlMapper result = new XmlMapper();
return result;
}
}
Output:
java.lang.AssertionError:
Expected :Root(cats=[Root.Cat(name=first cat), Root.Cat(name=second cat)], dogs=Root.Dog(name=first dog))
Actual :Root(cats=[Root.Cat(name=second cat)], dogs=Root.Dog(name=first dog))
As you can see, first cat
is absent in deserialized object.
I saw #201, but it is not this bug about.
Issue Analytics
- State:
- Created 6 years ago
- Comments:5 (2 by maintainers)
Top Results From Across the Web
Deserialize flat array in XML by Jackson to List of Pojo
It is used when we have collections of nodes but they are unwrapped. After these two simple paragraphs let's deserialize your case.
Read more >How do I deserialize this XML array? - Google Groups
Hi,. How would I go about deserializing this array of mixed elements? <result>
Read more >Jackson 2.12: improved XML module - cowtowncoder - Medium
Root value deserialization works similar to property values ... typically not support by data-binding XML libraries, called mixed content, ...
Read more >Examples of XML Serialization | Microsoft Learn
These code examples show advanced scenarios, including how to use XML serialization to generate an XML stream that conforms to an XML Schema ......
Read more >Jakarta XML Binding
The Unmarshaller class governs the process of deserializing XML data into a ... then the sequence of values in the array are first...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
I looked inside.
I think the problem is that
MethodProperty.deserializeAndSet
uses methodCollectionDeserializer.deserialize(JsonParser, DeserializationContext)
but notCollectionDeserializer.deserialize(JsonParser, DeserializationContext, Collection<Object>)
.If i expicity define setter which accumulates all passed values (not just sets field), all works.
So this is a workaround.
@naXa777 Jackson does not ignore unwrapped lists when using
annotation.