JaxB распаковывает пользовательский XML

В настоящее время я пытаюсь разобрать некоторый существующий XML на несколько классов, которые я создал вручную. Проблема в том, что я всегда получаю сообщение об ошибке, которое говорит мне, что JaxB ожидает элемент погоды, но находит элемент погоды. (?)

javax.xml.bind.UnmarshalException: неожиданный элемент (URI: «http://www.aws.com/aws», локальный: «погода»). Ожидаемые элементы: ‹{}api>,‹{}location>,‹{}weather>.

Я пробовал с и без «aws:» в названии элементов.

Вот мой класс погоды:

@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;
    }
}

И это XML, который я пытаюсь разобрать:

<?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>

Я не совсем уверен, что я делаю неправильно. Любые подсказки? Я подозреваю, что проблема заключается в определении xmlns, но я понятия не имею, что с этим делать. (Вы можете убедиться в этом, взглянув на свойство uri. Это была неудачная идея. ^^) И да, я действительно пытался установить пространство имен, но это скорее установка uri пространства имен, а не его... имя.


person annih    schedule 25.07.2012    source источник


Ответы (2)


вам нужны пространства имен в вашем коде. префиксы пространств имен бессмысленны, вам нужно фактическое пространство имен (например, "http://www.aws.com/aws").

@XmlRootElement(name = "weather", namespace="http://www.aws.com/aws")
person jtahlborn    schedule 25.07.2012
comment
o.o Ладно... это было совершенно глупо с моей стороны. Я должен был попробовать URI вместо имени, как только заметил, что он установлен и генерирует имя. Но... мне нужно определить его для каждого @XmlAttribute/@XmlElement? Нет ли более простого способа? (Не работает, если я помещаю его только в каждый @XmlRootElement.) - person annih; 25.07.2012
comment
@annih - Вам не нужно указывать это каждый раз. Вы можете использовать аннотацию @XmlSchema для класса package-info, чтобы указать квалификацию пространства имен для вашей модели: stackoverflow.com/a/11652942/383861 - person bdoughan; 25.07.2012

Я бы рекомендовал добавить класс package-info в вашу модель домена с аннотацией @XmlSchema, чтобы указать квалификацию пространства имен:

информация о пакете

@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;

Примечание

Ваша аннотация XmlRootElement и @XmlElement не должна содержать префикс пространства имен. У вас должно быть @XmlRootElement(name = "weather") вместо @XmlRootElement(name = "aws:weather")

Для получения дополнительной информации

person bdoughan    schedule 25.07.2012
comment
^^ Я подозревал, что вы ответите на этот вопрос. Я нашел много других ваших сообщений на SO при поиске полезных сообщений. Большое спасибо. Я не был полностью осведомлен о возможностях @XmlSchema. - person annih; 25.07.2012