21

I am trying to unmarshal an XML.

This is what my XML looks like

<DeviceInventory2Response xmlns="http://tempuri.org/">
<DeviceInventory2Result xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <Obj123 xmlns="">
     <Id>1</Id>
     <Name>abc</Name>
  </Obj123>
  <Obj456 xmlns="">
  .
  .
  .

I am trying to get Id and Name under Obj123. However when I run my unmarshal command I get the following error.

An Error:  javax.xml.bind.UnmarshalException: unexpected element (uri:"http://tempuri.org/", local:"DeviceInventory2Response"). Expected elements are (none)

My code looks like this in the main class:

Obj123 myObj123 = (Obj123) unmarshaller.unmarshal(inputSource);

And my class for Obj123 looks like this:

package com.myProj.pkg;

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


@XmlRootElement(name="Obj123")
public class Obj123 {

  private String Id;
  private String Name;

  public String getId() {
    return Id;
  }

  public String getName() {
    return Name;
  }
}

I thought by setting my XMLRootElement that I should be able to skip the first 2 lines of my XML but that doesn't seem to be happening. Any ideas?

Edit:

This is how my JAXB Context is made:

JAXBContext jaxbContext = JAXBContext.newInstance();
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Obj123 obj123 = (Obj123) unmarshaller.unmarshal(xmlStreamReader);
dev
  • 1,477
  • 5
  • 18
  • 43
  • You should get rid of the first two lines. Or use another object 'DeviceInventory2Result' make it a root element and add the Obj123 as the child to it. – Zeus Dec 05 '13 at 20:43
  • I unfortunately cannot edit the XML at all. Is making another class the only way to do it? No way to ignore them? – dev Dec 05 '13 at 20:44
  • I guess, you can ignore the child elements, but not the parent. – Zeus Dec 05 '13 at 20:53

3 Answers3

19

I solved the problem by adding

@XmlRootElement(name="abc_xxx") to the Root class.
(where abc_XXX is the root tag of your XML)

The JAXB classes generated by eclipse didn't add this annotation to my root class.

Vibha
  • 939
  • 9
  • 17
  • 1
    Wow, this is amazing solution. I wonder why this annotation is not added automatically? – zygimantus Sep 16 '16 at 17:31
  • Thanks, this also was the solution for me – Emiliano Nov 28 '19 at 20:21
  • Solved the problem by generating XMLRootElement, using the solution by Rasto here: https://stackoverflow.com/questions/42582550/want-xmlrootelement-in-classes-generated-by-jaxb2-maven-plugin – Kjeld Jul 15 '23 at 16:40
13

JAXB implementations will try to match on the root element of the document (not on a child element). If you want to unmarshal to the middle of an XML document then you can parse the document with StAX advance the XMLStreamReader to the desired element and then unmarshal that.

For More Information

UPDATE

now I am getting the following error. An Error: javax.xml.bind.UnmarshalException - with linked exception: [javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"Obj123"). Expected elements are (none)].

A JAXBContext only knows about the classes you tell it about. Instead of:

JAXBContext jaxbContext = JAXBContext.newInstance();

You need to do:

JAXBContext jaxbContext = JAXBContext.newInstance(Obj123.class);
bdoughan
  • 147,609
  • 23
  • 300
  • 400
  • Ok cool. I went through that and it def. seems to be what I was looking for. However, once I implemented it I got the following error: Method getLocalName() cannot be called for START_DOCUMENT event. Any Ideas why that would happen? – dev Dec 06 '13 at 14:10
  • @CameronJones - You need to advance past the START_DOCUMENT event before you call getLocalName(). – bdoughan Dec 06 '13 at 14:12
  • Ah okay. I missed your first .nextTag() call. I fixed that but now I am getting the following error. An Error: javax.xml.bind.UnmarshalException - with linked exception: [javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"Obj123"). Expected elements are (none)]. I think this is more of an issue with my Obj123 class and not with the Unmarshling process, though. – dev Dec 06 '13 at 15:36
  • @CameronJones - How are you creating your `JAXBContext`? – bdoughan Dec 06 '13 at 15:38
  • @CameronJones - I have updated my answer with the information you need to solve that problem. – bdoughan Dec 06 '13 at 15:59
  • Perfect. I was unaware of that with the JAXBContext. Must have missed it in the documentation. Thanks a ton. – dev Dec 06 '13 at 16:21
10

Use ObjectFactory class instead like

JAXBContext jaxbContext = null;
try {
    jaxbContext = JAXBContext.newInstance(ObjectFactory.class);
} catch (JAXBException e) {
    e.printStackTrace();
}

JAXBElement<ObjectFactory> applicationElement = null;
try {
    applicationElement = (JAXBElement<ObjectFactory>)
    unmarshaller.unmarshal(Thread.currentThread().getClass()
        .getResourceAsStream(fileName));
} catch (JAXBException e) {
    e.printStackTrace();
}

Try this and will resolve above problem. My problem has been resolved.

David
  • 2,987
  • 1
  • 29
  • 35
Sushil
  • 101
  • 1
  • 2
  • 1
    `JAXBContext.newInstance(ObjectFactory.class);` is correct, but you stil lhave to cast the resulting object to `(JAXBElement)`, not to `(JAXBElement)`. Good tip, though – mp_loki Aug 04 '17 at 19:26