132

I encountered an exception when unmarshalling from XML:

 unexpected element (uri:"", local:"Group"). Expected elements are <{}group> 

Group class has no annotations and group.xml just contains data.

 JAXBContext jc = JAXBContext.newInstance(Group.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); Group group = (User)unmarshaller.unmarshal(new File("group.xml")); 

What could be the cause?

1
  • 12
    For those coming here from a search, I just want to comment that this can be caused by using the incorrect ObjectFactory from generated-sources, which is more likely if you are mixing two different generated source directories. Commented May 6, 2017 at 1:28

16 Answers 16

139

It looks like your XML document has the root element "Group" instead of "group". You can:

  1. Change the root element on your XML to be "group"
  2. Add the annotation @XmlRootElement(name="Group") to the Group classs.
Sign up to request clarification or add additional context in comments.

5 Comments

It solved the problem, Thanks! I used the second solution , @XmlRootElement(name="Group"). My class name is Group, and XML root element is Group, why I still need name="Group"
@BlaiseDoughan I'm having the exactly opposite problem, I have @XmlRootElement(name = "MB") @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "MB", propOrder = { "date", "time" }) but i'm getting unexpected element (uri:"http://xx.title.com/new/response", local:"MB"). Expected elements are <{}Date>,<{}MB>,<{}Time> i also have @XmlElement(name="Date", required = true) over each field. Where & Why is it going wrong? I've also tried removing @XmlRootElement!
There was an issue with @XmlSchema in package-info.java, fixed now.
This answer is fully misslieading @Glenn Mason one is the good one I believe.
58

Luckily, the package-info class isn't required. I was able to fix mine problem with iowatiger08 solution.

Here is my fix showing the error message to help join the dots for some.

Error message

javax.xml.bind.UnmarshalException: unexpected element (uri:"http://global.aon.bz/schema/cbs/archive/errorresource/0", local:"errorresource"). Expected elements are <{}errorresource>

Code before fix

@XmlAccessorType(XmlAccessType.FIELD) @XmlType(name="", propOrder={"error"}) @XmlRootElement(name="errorresource") public class Errorresource 

Code after fix

@XmlAccessorType(XmlAccessType.FIELD) @XmlType(name="", propOrder={"error"}) @XmlRootElement(name="errorresource", namespace="http://global.aon.bz/schema/cbs/archive/errorresource/0") public class Errorresource 

You can see the namespace added to @XmlRootElement as indicated in the error message.

2 Comments

Faced the same issue and followed your comment and the issue is resolved. Thank you.
Thank you! same issue and I was able to fix it by following this.
42

You need to put package-info.java in your generated jaxb package. Its content should be something like that

@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.example.org/StudentOperations/") package generated.marsh; 

Comments

11

After looking more, the root element has to be associated with a schema-namespace as Blaise is noting. Yet, I didnt have a package-info java. So without using the @XMLSchema annotation, I was able to correct this issue by using

@XmlRootElement (name="RetrieveMultipleSetsResponse", namespace = XMLCodeTable.NS1) @XmlType(name = "ns0", namespace = XMLCodeTable.NS1) @XmlAccessorType(XmlAccessType.NONE) public class RetrieveMultipleSetsResponse {//...} 

Hope this helps!

Comments

9

Most likely you might not have the scenario I was having. My issue was that the model classes (in a jar) had the javax package while the processor, the consumer of model classes, expected the jakarta package.

2 Comments

This was my scenario too. My model classes were in a jar and were using import javax.xml.bind.annotation.XmlRootElement while the processor (jakarta.xml.bind-api 4.0.x) expected import jakarta.xml.bind.annotation.XmlRootElement. Upvoted
I am facing the similar issue after upgrading from Java 11 to Java 21, which is using the jakarta packages. What is the solution in this case?
8

This is a fix for a pretty niche use case but it gets me each time. If you are using the Eclipse Jaxb generator it creates a file called package-info.

@javax.xml.bind.annotation.XmlSchema(namespace = "blah.xxx.com/em/feed/v2/CommonFeed") package xxx.blah.mh.domain.pl3xx.startstop; 

If you delete this file it will allow a more generic xml to be parsed. Give it a try!

1 Comment

It woked perfect after that.. Thanks alot mate.. :) . I just made the namespace mentioned to empty string.
6

So i had your exception when i used pre-generated classes from a xsd file that was not mine.

The generated xml-object name and namespace(the @xmlroot) was missing from the java-class, so i could not unmarshal it. Putting the missing URI above the class like this "solved" the problem:

@XmlRootElement(name = "XHE", namespace = "http://docs.oasis-open.org/bdxr/ns/XHE/1/ExchangeHeaderEnvelope") public class XHEType { 

But since i wanted this class to only be in target, this did not suffice. What i finally came up with was this new class to wrap the generated class in where i put the @xmlroot instead:

@XmlRootElement(name = "XHE", namespace = "http://docs.oasis-open.org/bdxr/ns/XHE/1/ExchangeHeaderEnvelope") public class XHEType2 extends XHEType { 

And the unmarshall code:

 JAXBContext jaxbContext = JAXBContext.newInstance(XHEType2.class); javax.xml.bind.Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); XHEType xheType = (XHEType) unmarshaller.unmarshal(reader); 

Comments

4

None of the solutions mentioned here worked for me, I was still getting:

Exception in thread "main" javax.xml.bind.UnmarshalException: unexpected element (uri:"java:XXX.XX.XX.XXX", local:"XXXXX")

After lot of research through other sites below code worked for me-

FileInputStream fis = new FileInputStream("D:/group.xml"); SOAPMessage message = factory.createMessage(new MimeHeaders(), fis); JAXBContext jc = JAXBContext.newInstance(Group.class); Unmarshaller u = jc.createUnmarshaller(); JAXBElement<Group> r = u.unmarshal(message.getSOAPBody().extractContentAsDocument(), Group.class); Group group = r.getValue(); 

Comments

2

I had the same problem.. It helped me, I'm specify the same field names of my classes as the tag names in the xml file (the file comes from an external system).

For example:

My xml file:

<Response> <ESList> <Item> <ID>1</ID> <Name>Some name 1</Name> <Code>Some code</Code> <Url>Some Url</Url> <RegionList> <Item> <ID>2</ID> <Name>Some name 2</Name> </Item> </RegionList> </Item> </ESList> </Response> 

My Response class:

@XmlRootElement(name="Response") @XmlAccessorType(XmlAccessType.FIELD) public class Response { @XmlElement private ESList[] ESList = new ESList[1]; // as the tag name in the xml file.. // getter and setter here } 

My ESList class:

@XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name="ESList") public class ESList { @XmlElement private Item[] Item = new Item[1]; // as the tag name in the xml file.. // getters and setters here } 

My Item class:

@XmlRootElement(name="Item") @XmlAccessorType(XmlAccessType.FIELD) public class Item { @XmlElement private String ID; // as the tag name in the xml file.. @XmlElement private String Name; // and so on... @XmlElement private String Code; @XmlElement private String Url; @XmlElement private RegionList[] RegionList = new RegionList[1]; // getters and setters here } 

My RegionList class:

@XmlRootElement(name="RegionList") @XmlAccessorType(XmlAccessType.FIELD) public class RegionList { Item[] Item = new Item[1]; // getters and setters here } 

My DemoUnmarshalling class:

public class DemoUnmarshalling { public static void main(String[] args) { try { File file = new File("..."); JAXBContext jaxbContext = JAXBContext.newInstance(Response.class); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); jaxbUnmarshaller.setEventHandler( new ValidationEventHandler() { public boolean handleEvent(ValidationEvent event ) { throw new RuntimeException(event.getMessage(), event.getLinkedException()); } } ); Response response = (Response) jaxbUnmarshaller.unmarshal(file); ESList[] esList = response.getESList(); Item[] item = esList[0].getItem(); RegionList[] regionLists = item[0].getRegionList(); Item[] regionListItem = regionLists[0].getItem(); System.out.println(item[0].getID()); System.out.println(item[0].getName()); System.out.println(item[0].getCode()); System.out.println(item[0].getUrl()); System.out.println(regionListItem[0].getID()); System.out.println(regionListItem[0].getName()); } catch (JAXBException e) { e.printStackTrace(); } } } 

It gives:

1 Some name 1 Some code Some Url 2 Some name 2 

Comments

2

If none of the above works, try adding

@XmlRootElement(name="Group") to the Group classs.

1 Comment

I have deleted package-info.java and it’s working
1

I had the same issue. I added following attributes to <xs:schema..> elementFormDefault="qualified" attributeFormDefault="unqualified"

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.example.com/schemas/ArrayOfMarketWithStations" targetNamespace="http://www.example.com/schemas/ArrayOfMarketWithStations" elementFormDefault="qualified" attributeFormDefault="unqualified" > 

and re-generated java classes by running xjc, which corrected package-info.java.

@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.example.com/schemas/ArrayOfMarketWithStations", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED) 

This fixed the issue for me.

Comments

1

You need to put package-info.java class in package of contextPath and put below code in same class:

@javax.xml.bind.annotation.XmlSchema(namespace = "https://www.namespaceUrl.com/xml/", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED) package com.test.valueobject; 

Comments

1

I already have the same problem and I just change as below:

@XmlRootElement -> @XmlRootElement(name="Group") 

Comments

1

In case you are going crazy because this happens only in your Tests and you are using PowerMock this is the solution, add it on top of your test class:

@PowerMockIgnore({ "javax.xml.*", "org.xml.*", "org.w3c.*" }) 

Comments

0

Same to me. The name of the mapping class was Mbean but the tag root name was mbean so I had to add the annotation:

@XmlRootElement(name="mbean") public class MBean { ... } 

Comments

0

I had the same issue, my problem was, that I had two different webservices with two different wsdl-files. I generated the sources in the same package for both webservices, which seems to be a problem. I guess it's because of the ObjectFactory and perhaps also because of the package-info.java - because those are only generated once.

I solved it, by generating the sources for each webservice in a different package. This way, you also have two different ObjectFactories and package-info.java files.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.