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

@JsonUnwrapped does not work inside list

Open SimonCockx opened this issue 4 months ago • 2 comments

@JsonUnwrapped does not unwrap items inside a list. Below is a minimal example of what I'm trying to achieve.

I'm trying to model the following simple XSD scheme in Java.

<xs:element name="document" type="Document" />
<xs:complexType name="Document">
  <xs:sequence maxOccurs="unbounded">
    <xs:element name="a" type="xs:string" />
    <xs:element name="b" type="xs:string" />
  </xs:sequence>
</xs:complexType>

There is one type Document which contains a sequence of alternating a and b elements. E.g., this is a valid XML instance:

<document>
  <a>A1</a>
  <b>B1</b>
  <a>A2</a>
  <b>B2</b>
  <a>A3</a>
  <b>B3</b>
</document>

I tried to represent this in Java using the following classes:

@JacksonXmlRootElement(localName = "document")
public class Document {
    private List<ABPair> abPairs = new ArrayList<>();

    @JsonUnwrapped
    @JacksonXmlElementWrapper(useWrapping = false)
    public List<ABPair> getABPairs() {
        return abPairs;
    }
    public Document addABPair(ABPair pair) {
        abPairs.add(pair);
        return this;
    }
}

public static class ABPair {
    private String a;
    private String b;
    
    public String getA() {
        return a;
    }
    public String getB() {
        return b;
    }

    public ABPair setA(String a) {
        this.a = a;
        return this;
    }
    public ABPair setB(String b) {
        this.b = b;
        return this;
    }
}

However, the @JsonUnwrapped does not seem to work in conjunction with useWrapping = false. Unit test reproducing the problem:

@Test
public void test() throws JsonProcessingException {
    XmlMapper mapper = new XmlMapper();

    Document document =
            new Document()
                    .addABPair(new ABPair().setA("A1").setB("B1"))
                    .addABPair(new ABPair().setA("A2").setB("B2"))
                    .addABPair(new ABPair().setA("A3").setB("B3"));
    assertEquals("<document><a>A1</a><b>B1</b><a>A2</a><b>B2</b><a>A3</a><b>B3</b></document>", mapper.writeValueAsString(document));
}

The actual result is "<document><abpairs><a>A1</a><b>B1</b></abpairs><abpairs><a>A2</a><b>B2</b></abpairs><abpairs><a>A3</a><b>B3</b></abpairs></document>".

Is there a way to get this working in Jackson?

SimonCockx avatar Oct 22 '24 13:10 SimonCockx