user4424299
user4424299

Reputation:

How to parse attributes in a nested node with JAXB?

I'm trying to parse a XML file created with the omdbAPI. The XML-file looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<root response="True">
   <movie
        title="Fifty Shades of Grey"
        year="2015"
        ...
        plot="..."
        imdbRating="4.2"
        imdbID="tt2322441"
        type="movie" />
</root>

And my class that JAXB uses looks like this:

@XmlRootElement(name = "movie")
public class IMDBInfo {
    private String plot;
    private String imdbRating;

    @XmlAttribute(name = "plot")
    public void setPlot(String plot){
        this.plot = plot;
    }

    @XmlAttribute(name = "imdbID")
    public void setImdbRating(String imdbRating){
        this.imdbRating = imdbRating;
    }

    public String getPlot(){
        return plot;
    }

    public String getImdbRating(){
        return imdbRating;
    }
}

This keeps giving me JAXBExceptions. What's wrong with my JAXB-annotations?

Upvotes: 0

Views: 1427

Answers (1)

Stephan
Stephan

Reputation: 43053

The XML hierarchy is like this root/movie.

With JAXB, you must recreate this hierarchy. This is why @XmlRootElement(name = "movie") is invalid here.

However, JAXB allows you to map an attribute from an XML source to a class field automatically as long as both attribute and field share the same name.

To sum up all the previous points, here is a working example for the input XML:

One option...

IMDBInfo.java

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "root")
public class IMDBInfo {

    @XmlElement
    private Movie movie;

    public Movie getMovie() {
        return movie;
    }
}

Movie.java

import javax.xml.bind.annotation.XmlAttribute;

public class Movie {
    @XmlAttribute
    private String plot;

    @XmlAttribute
    private String imdbRating;

    public String getPlot() {
        return plot;
    }

    public String getImdbRating() {
        return imdbRating;
    }
}

Sample Usage

public static void main(String[] args) {
    try {

        File file = new File("file.xml");
        JAXBContext jaxbContext = JAXBContext.newInstance(IMDBInfo.class);

        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
        IMDBInfo imdbInfo = (IMDBInfo) jaxbUnmarshaller.unmarshal(file);
        Movie movie = imdbInfo.getMovie();

        System.out.format(//
                "ImdbRating: %s\nPlot: %s\n", //
                movie.getImdbRating(), //
                movie.getPlot() //
                );

    } catch (JAXBException e) {
        e.printStackTrace();
    }
}

Output

ImdbRating: 4.2
Plot: When Anastasia Steele, a literature student, goes to interview the wealthy Christian Grey as a favor to her roommate Kate Kavanagh, she encounters a beautiful, brilliant and intimidating man. The innocent and naive Ana starts to realize she wants him. Despite his enigmatic reserve and advice, she finds herself desperate to get close to him. Not able to resist Ana's beauty and independent spirit, Christian Grey admits he wants her too, but on his own terms. Ana hesitates as she discovers the singular tastes of Christian Grey - despite the embellishments of success, his multinational businesses, his vast wealth, and his loving family, Grey is consumed by the need to control everything.

... and other options

Upvotes: 2

Related Questions