7
<a>
    <b1>b1</b1>
    <b2>b2</b2>
    <b3>
        <c1></c1>
        <c2></c2>
    </b3>
    <b3>
        <c1></c1>
        <c2></c2>
    </b3>
    <b3>
        <c1></c1>
        <c2></c2>
    </b3>
</a>

Since all the <b3> are not included in a wrapper element, say <b3s> when I use Jackson XmlMapper to read the XML file to my POJO Java Bean class, I got exception

com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [simple type, class com.xxxxx] from String value; no single-String constructor/factory method (through reference chain: com.xxxx["xxx"]->com.xxx["xxx"])

What annotation shall I use?

@XmlElement
public List<B3> b3;
bdoughan
  • 147,609
  • 23
  • 300
  • 400
James Yu
  • 153
  • 1
  • 4

3 Answers3

6

If you want to use "unwrapped" representation, you need to use Jackson 2.1, and indicate unwrapped option:

@JacksonXmlElementWrapper(useWrapping=false)

alternatively, if using JAXB annotations, default should be not to use wrapping.

Finally, you can also change the default not to use wrapper element, with:

JacksonXmlModule module = new JacksonXmlModule();
// to default to using "unwrapped" Lists:
module.setDefaultUseWrapper(false);
XmlMapper xmlMapper = new XmlMapper(module);
StaxMan
  • 113,358
  • 34
  • 211
  • 239
5

NOTE

Jackson is not a JAXB (JSR-222) compliant implementation. This means there are no guarantees on how it interprets the standard JAXB annotations


By default a JAXB (JSR-222) compliant implementation does not apply a wrapper element to collection properties.

A

By default a JAXB (JSR-222) implementation will default mappings based on the properties. To save space I have omitted those methods and specified @XmlAccessorType(XmlAccessType.FIELD) so that the metadata will be derived from the instance variables (fields).

package forum13097559;

import java.util.List;
import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class A {

    private String b1;
    private String b2;
    private List<B3> b3;

}

B3

package forum13097559;

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
public class B3 {

    private String c1;
    private String c2;

}

Demo

package forum13097559;

import java.io.File;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(A.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum13097559/input.xml");
        A a = (A) unmarshaller.unmarshal(xml);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(a, System.out);
    }

}

input.xml/Output

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<a>
    <b1>b1</b1>
    <b2>b2</b2>
    <b3>
        <c1></c1>
        <c2></c2>
    </b3>
    <b3>
        <c1></c1>
        <c2></c2>
    </b3>
    <b3>
        <c1></c1>
        <c2></c2>
    </b3>
</a>

For More Information

bdoughan
  • 147,609
  • 23
  • 300
  • 400
0

Jackson does not know how to turn a string into an instance of B3. Add a constructor (or factory method which returns a B3) to B3 which takes a single String. Constructor example:

class B3 {
    // ...
    public B3(String value) {
       // do something with value 
    }
    // ...
}

http://wiki.fasterxml.com/JacksonFeatureCreators

Matt Ball
  • 354,903
  • 100
  • 647
  • 710