0

I'm using JAXB to unmarshal some http client response with Spring Boot 3.0.8 & Java 17,

<dependency>
  <groupId>jakarta.xml.bind</groupId>
  <artifactId>jakarta.xml.bind-api</artifactId>
  <version>4.0.0</version>
</dependency>

<dependency>
  <groupId>com.sun.xml.bind</groupId>
  <artifactId>jaxb-impl</artifactId>
  <version>4.0.3</version>
</dependency>

But when I use @XmlElementWrapper, I get empty list

here is the complete code :

foo.xml

<foo xmlns='http://ns.fredhopper.com/XML/output/6.1.0' name='hello'>
    <bars>
        <bar name='hello bar 1'/>
        <bar name='hello bar 2'/>
    </bars>
</foo>

Foo.java

import jakarta.xml.bind.annotation.XmlAccessType;
import jakarta.xml.bind.annotation.XmlAccessorType;
import jakarta.xml.bind.annotation.XmlAttribute;
import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlElementWrapper;
import jakarta.xml.bind.annotation.XmlRootElement;
import java.util.List;
import lombok.Data;

@Data
@XmlRootElement(name = "foo", namespace = "my-secret-name-space")
@XmlAccessorType(XmlAccessType.FIELD)
public class Foo {

  @XmlAttribute private String name;


  @XmlElementWrapper(name = "bars", namespace = "my-secret-name-space")
  @XmlElement(name = "bar")
  private List<Bar> bars;

}

Bar.java

import jakarta.xml.bind.annotation.XmlAccessType;
import jakarta.xml.bind.annotation.XmlAccessorType;
import jakarta.xml.bind.annotation.XmlAttribute;
import jakarta.xml.bind.annotation.XmlTransient;
import lombok.Data;

@Data
@XmlAccessorType(XmlAccessType.NONE)
public class Bar {

  @XmlAttribute private String name;

}

unmarshling code

try (InputStream inputStream = getSomeInputStream()) {
  JAXBContext context = JAXBContext.newInstance(Foo.class);
  return (Foo) context.createUnmarshaller().unmarshal(inputStream);
}

in my Foo class i got the name attribute correctly initialized, but the bars list is empty

Hayi
  • 6,972
  • 26
  • 80
  • 139

1 Answers1

1

Seems you are simply missing the namespace on the @XmlElement for bar.

For me, it worked as expected, when I added that:

@Data
@XmlRootElement(name = "foo", namespace = "http://ns.fredhopper.com/XML/output/6.1.0")
@XmlAccessorType(XmlAccessType.FIELD)
public class Foo {

    @XmlAttribute private String name;
    
    @XmlElementWrapper(name = "bars", namespace = "http://ns.fredhopper.com/XML/output/6.1.0")
    @XmlElement(name = "bar", namespace = "http://ns.fredhopper.com/XML/output/6.1.0")
    private List<Bar> bars;
}

And I used the Foo.class when creating the JAXBContext:

JAXBContext context = JAXBContext.newInstance(Foo.class);
foo = (Foo) context.createUnmarshaller().unmarshal(inputStream);
Jochen Reinhardt
  • 833
  • 5
  • 14
  • yeah thanks man that was the root cause, but is there some is there some setting to set the namespace globally ? – Hayi Sep 01 '23 at 13:53
  • I found this question: https://stackoverflow.com/questions/43721186/namespace-with-no-prefix-in-jaxb - you just have to create a package-info.java for your Jaxb-Classes and configure the namespace at package level. @XmlSchema(namespace = "http://ns.fredhopper.com/XML/output/6.1.0", elementFormDefault = XmlNsForm.QUALIFIED ) - that did the trick for me. – Jochen Reinhardt Sep 01 '23 at 14:20