1
votes

I have a problem.

I have the following XML:

<vehicles>
   <Train name="train1" />
  <Train name="train2" />
   <Train name="train3" />
   <Car name="car1" />
   <Car name="car2" />
   <Car name="car3" />
</vehicles>

I created an object:

@XmlRootElement(name="Car")
public class Car 
{
   private String name;

   public Car() { super(); }

   @XmlAttribute(name="name")
   public String getName() { return name; }

   public String setName(String name) { this.name = name; }
}

Now I am trying to use JAXB in order to generate Car objects from the XML calling the following method:

bindObjectsFromXml(file, Car.class);

public static <T> List<T> bindObjectsFromXml(File file, Class<T> klazz, String[] rootElementsNames) throws Exception
{
    List<T> objects = new LinkedList<T>();

    XMLStreamReader xmlStreamReader = getXMLStreamReader(file);
    JAXBContext context = JAXBContext.newInstance(klazz);
    Unmarshaller unmarshaller = context.createUnmarshaller();

    xmlStreamReader.nextTag();

    for ( String rootElement : rootElementsNames ) // there might be more than one root that we want to skip
    {
        xmlStreamReader.require( XMLStreamConstants.START_ELEMENT, null, rootElement );
        xmlStreamReader.nextTag();
    }

    while ( xmlStreamReader.getEventType() == XMLStreamConstants.START_ELEMENT )
    {
        JAXBElement<T> jaxbElement = unmarshaller.unmarshal(xmlStreamReader, klazz);
        T klazzInstance = jaxbElement.getValue();
        objects.add( klazzInstance );

        if (xmlStreamReader.getEventType() == XMLStreamConstants.CHARACTERS) 
        {
            xmlStreamReader.next();
        }
    }

    return objects;
}

The problem is that I get Car object also from Train.

I don't understand why the unmarshaller ignores the @XmlRootElement(name="Car")?

Can you please help me with this?

Thank you very much in advance.

1
Your parameters for bindObjectsFromXml don't match. You're calling it with 2 arguments, and declaring 3 parameters.skaffman
Also, "I get Car object also from Train" doesn't make sense. Please explain more clearly.skaffman

1 Answers

0
votes

You need to ensure that your JAXBContext is aware of all the classes that you want to map to. In your example code you build the JAXBContext on Car.class so it will not be aware of Train.class. You will need to do the following:

JAXBContext jc = JAXBContext.newInstance(Car.class, Train.class);