JAXB Error: unexpected element when unmarshalling

java, jax-rs, jaxb, jersey

Solution

The class you're creating the JAXBContext from is Item.class, but the XML contains a list called items which in turn contains distinct item entries. You would need another class that wraps a

List<Item>

for this to work.

Here's a full working example:

The Items class:

import java.util.List;

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

@XmlRootElement
public class Items {

    private List<Item> items;

    @XmlElement(name="item")
    public List<Item> getItems() {
        return items;
    }

    public void setItems(List<Item> items) {
        this.items = items;
    }

}

Note that there is an @XmlElement annotation on the items property, because the actual elements are called "item" in the XML.

The Item class:

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

public class Item {

    private String itemID;
    private String itemDescription;

    // need to have a constructor with no params
    public Item() {}

    public Item(String itemID, String itemDescription) {
        this.itemID = itemID;
        this.itemDescription = itemDescription;
    }

    @XmlAttribute
    public String getId() {
        return itemID;
    }

    public void setId(String id) {
        itemID = id;
    }

    @XmlElement
    public String getDescription() {
        return itemDescription;
    }

    public void setDescription(String description) {
        itemDescription = description;
    }
}

And a unit test:

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import org.junit.Test;

public class JAXBTest {

    @Test
    public void xmlIsUnmarshalled() throws JAXBException {
        JAXBContext context = JAXBContext.newInstance(Items.class);
        Unmarshaller um = context.createUnmarshaller();
        Items items = (Items) um.unmarshal(new File("items.xml"));

        assertNotNull(items);
        assertNotNull(items.getItems());
        assertEquals(2, items.getItems().size());

        assertEquals("Chinos", items.getItems().get(0).getDescription());
        assertEquals("Trousers", items.getItems().get(1).getDescription());

        assertEquals("1", items.getItems().get(0).getId());
        assertEquals("2", items.getItems().get(1).getId());
    }
}

Problem

Could someone help me understand why I'm getting this error: javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"items"). Expected elements are <{}item> I've new to JAX-B but been stuck on this all day, I really don't understand whats happening and any help is really appreciated, thanks a lot. Item Class: @XmlRootElement ``` public class Item { private String itemID; private String itemDescription; //need to have a constructor with no params public Item(){ } //Constructor: sets object vars public Item(String itemID, String itemDescription) { this.itemID = itemID; this.itemDescription = itemDescription; } @XmlAttribute //getters and setters public String getID() { return itemID; } public void setId(String id) { itemID= id; } @XmlElement public String getDescription() { return itemDescription; } public void setDescription(String description) { itemDescription = description; } ``` Unmarshalling code: ``` resource = client.resource("http://localhost:8080/testProject/rest/items"); ClientResponse response= resource.get(ClientResponse.class); String entity = response.getEntity(String.class); System.out.println(entity); JAXBContext context = JAXBContext.newInstance(Item.class); Unmarshaller um = context.createUnmarshaller(); Item item = (Item) um.unmarshal(new StringReader(entity)); And this is the XML i'm trying to parse: <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <items> <item id="1"> <description>Chinos</description> </item> <item id="2"> <description>Trousers</description> </item> </items> ``` Here is the Web Service that is creating the XML: ``` @GET @Produces(MediaType.TEXT_XML) public List<Item> getItemsBrowser(){ java.sql.Connection connection; java.sql.Statement statement; List<Item> items = new ArrayList<Item>(); ResultSet resultSet = null; try { connection = dataSource.getConnection(); statement = connection.createStatement(); String query = "SELECT * FROM ITEMS"; resultSet = statement.executeQuery(query); // Fetch each row from the result set while (resultSet.next()) { String a = resultSet.getString("itemID"); String b = resultSet.getString("itemDescription"); //Assuming you have a user object Item item = new Item(a, b); items.add(item); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return items; } ```

Original source