Josh
Josh

Reputation: 1356

JAXB unmarshal mystery XML

I am using JAXB to unmarshal an XML file.

All I know about the XML file is that it is valid XML.

How then am I supposed to specify a class and/or package to newInstance?

JAXBContext jaxbContext = JAXBContext.newInstance(??????);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Object o = (Object) unmarshaller.unmarshal(myFile);

I did not see anything in the docs that address this issue.

Upvotes: 2

Views: 874

Answers (2)

Xstian
Xstian

Reputation: 8282

In newInstance you must add the class root element that map your xml... below an example

Here an example ..

public static void main(String[] args) throws JAXBException {
        final JAXBContext context = JAXBContext.newInstance(Vehicals.class);
        final Marshaller m = context.createMarshaller();
        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

        final Vehicals vehicals = new Vehicals();

        List<Car> cars = new ArrayList<Car>();
        Car c = new Car();
        c.setName("Mercedes");
        cars.add(c);

        c = new Car();
        c.setName("BMW");
        cars.add(c);

        vehicals.setCar(cars);

        m.marshal(vehicals, System.out);
    }

Vehicals.java

import java.util.List;

import javax.xml.bind.annotation.XmlRootElement;

    @XmlRootElement
    public class Vehicals {

        private List<Car> Car;

        public List<Car> getCar() {
            return Car;
        }

        public void setCar(List<Car> cars) {
            this.Car = cars;
        }
    }

Car.java

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

@XmlRootElement
public class Car {

    @XmlTransient
    private Long id;

    private String name;

    @XmlTransient
    private String code;


    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
}

output.xml

<Vehicle>
     <Car>
         <name>Mercedes</name>
      </Car> 
     <Car>
         <name>BMW</name>
     </Car>
</Vehicle>

For the Unmarshal is the same thing. In my case i added Vehicals as parameter in newInstance method.

Upvotes: 0

Chris Hinshaw
Chris Hinshaw

Reputation: 7275

You need to tell JaxB what class to unmarshall to so that it can use the annotations in the class to resolve the hierarchy of the xml. You will need to have a class that is also annotated with something like @XmlRootElement. If you want to parse arbitrary xml you will probably need to do something with a DocumentBuilder or xpath.

See this artical for more info.

http://blog.bdoughan.com/2012/11/creating-generic-list-wrapper-in-jaxb.html

I have used something like this to convert arbitrary xml to a class. The any field will actually be a list of org.w3c.dom.Element in which you can get information from.

http://docs.oracle.com/javase/7/docs/api/org/w3c/dom/Element.html

@XmlRootElement
class Wrapper {
        /**
         * Everything else
         */
        @Transient
        @XmlAnyElement(lax = true)
        private List<Element> any;


        public List<Element> getAny() {
            return any;
        }

}

Upvotes: 5

Related Questions