XML unmarshalling using JAXB

2020-07-23 08:16发布

问题:

I have an XML file that I'm trying to unmarshal, but I cant figure out how to do it.

XML looks like

<config>
    <params>
        <param>
            <a>draft</a>
            <b>Serial</b>
        </param>
        <param>
            <a>amt</a>
            <b>Amount</b>
        </param>
    </params>
    <server>
        <scheme>http</scheme>
        <host>somehost.com/asdf</host>
    </server>
</config>

I could previously unmarshall when I had params as the root element and didnt have the server elements or config as root element.

I added a config class to try to unmarshall this, but I dont know where I'm going wrong.

My classes look like

@XmlRootElement
public class Config {

    private Params params = new Params();

    @XmlElement(name="params")
    public Params getParams() {
        return params;
    }
    public void setParam(Params params) {
        this.params = params;
    }
}

public class Params {
    private List<Param> params = new ArrayList<Param>();

    public List <Param> getParam() {
        return params;
    }

    public void setParam(List<Param> params) {
        this.params = params;
    }
}

public class Param {
    String a;
    String b;        
    //getters and setters.  omitted for brevity     
}   

unmarshal code

File file = new File("C:\\config.xml");
InputStream inputStream = new FileInputStream(file);
JAXBContext jc = JAXBContext.newInstance(Config.class);
Unmarshaller u = jc.createUnmarshaller();
conf = (Config) u.unmarshal(file);
System.out.println(conf.getParams().getParam().size());

the println prints 0. Where did I go wrong?

I know I dont have any code for the server nodes yet, havent gotten there yet. My actual XML doesnt have that node yet and I still cant get it to unmarshall the params correctly when inside the config tag.

回答1:

You just need to do following changes and it will work. Change setParams method in Config to

@XmlElement(name = "params") //<--Annotation added here
public void setParam(Params params) {
    this.params = params;
}


回答2:

try

@XmlRootElement
class Config {
    private List<Param> params = new ArrayList<Param>();

    @XmlElementWrapper
    @XmlElement(name="param")
    public List<Param> getParams() {
        return params;
    }

    public void setParams(List<Param> params) {
        this.params = params;
    }
}

class Param {
    String a;
    String b;
          ...
}


回答3:

I think both Param and it's wrapper should be unmarsh. You just unmarsh the list.But the Param model is also need to be unmarshed.



回答4:

By default a JAXB (JSR-222) implementation will treat all public fields and properties as mapped. A property is recognized as having matching get/set methods. You just need to change the setParam method in the Config class to setParams to match the getParams method.

@XmlRootElement
public class Config {

    private Params params = new Params();

    public Params getParams() {
        return params;
    }
    public void setParams(Params params) {
        this.params = params;
    }

}