1

I'm currently attempting to unmarshal some existing XML into a few classes I have created by hand. Problem is, I always get an error that tells me, JaxB expects a weather element but finds a weather element. (?)

javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.aws.com/aws", local:"weather"). Expected elements are <{}api>,<{}location>,<{}weather>

I tried with and without "aws:" in the elements' name.

Here's my weather class:

@XmlRootElement(name = "aws:weather")
public class WeatherBugWeather
{
    private WeatherBugApi api;
    private List<WeatherBugLocation> locations;
    private String uri;

    @XmlElement(name="aws:api")
    public WeatherBugApi getApi()
    {
        return this.api;
    }

    @XmlElementWrapper(name = "aws:locations")
    @XmlElement(name = "aws:location")
    public List<WeatherBugLocation> getLocations()
    {
        return this.locations;
    }

    public void setApi(WeatherBugApi api)
    {
        this.api = api;
    }

    public void setLocations(List<WeatherBugLocation> locations)
    {
        this.locations = locations;
    }

    @XmlAttribute(name="xmlns:aws")
    public String getUri()
    {
        return this.uri;
    }

    public void setUri(String uri)
    {
        this.uri = uri;
    }
}

And that's the XML I try to parse:

<?xml version="1.0" encoding="utf-8"?>
<aws:weather xmlns:aws="http://www.aws.com/aws">
    <aws:api version="2.0" />
    <aws:locations>
        <aws:location cityname="Jena" statename="" countryname="Germany" zipcode="" citycode="59047" citytype="1" />
    </aws:locations>
</aws:weather>

I'm not quite sure what I'm doing wrong. Any hints? I suspect the problem to be the xmlns definition, but I have no idea what to do about it. (You can see that by looking at the uri-property. That was one unsuccessful idea. ^^) And yes, I did try to set the namespace but that rather set's the namespace's uri instead of it's ... name.

annih
  • 395
  • 2
  • 6
  • 21

2 Answers2

3

I would recommend adding a package-info class in with your domain model with the @XmlSchema annotation to specify the namespace qualification:

package-info

@XmlSchema(
    namespace = "http://www.aws.com/aws",
    elementFormDefault = XmlNsForm.QUALIFIED)
package com.example.foo;

import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;

Note

Your XmlRootElement and @XmlElement annotation should not contain the namespace prefix. You should have @XmlRootElement(name = "weather") instead of @XmlRootElement(name = "aws:weather")

For More Information

bdoughan
  • 147,609
  • 23
  • 300
  • 400
  • 1
    ^^ I suspected you'd answer this. I found many of your other posts on SO while searching for helpful posts. Thanks very much. I was not totally aware of @XmlSchema's features. – annih Jul 25 '12 at 15:20
2

you need namespaces in your code. namespace prefixes are meaningless, you need the actual namespace (i.e. "http://www.aws.com/aws").

@XmlRootElement(name = "weather", namespace="http://www.aws.com/aws")
jtahlborn
  • 52,909
  • 5
  • 76
  • 118
  • o.o Okay... that was totally stupid of me. I should have tried the URI instead of the name once I noticed it set's that one and generates a name. But... I do have to define it at each and every @XmlAttribute/@XmlElement? Isn't there an easier way? (Does not work if I only put it in every @XmlRootElement.) – annih Jul 25 '12 at 15:02
  • 2
    @annih - You do not need to specify it each time. You can use the `@XmlSchema` annotation on a `package-info` class to specify the namespace qualification for your model: http://stackoverflow.com/a/11652942/383861 – bdoughan Jul 25 '12 at 15:14