Неожиданный элемент (uri:, local: element). Ожидаемые элементы: ‹{}link› ‹{}size›

При попытке распаковать этот xml:

<holder>
  <name>a</name>
  <elements>
    <element>
      <name>elem</name>
    </element>
  </elements>
</holder>

Я получаю ошибку unexpected element (uri:"", local:"element"). Expected elements are <{}link>,<{}totalSize> в ValidationEventHandler, а тег <elements> (и, следовательно, поле elements в классе Holder) игнорируется.

При генерации XML оба link и totalSize не выводятся, так как они равны нулю.

МОДЕЛЬ JAVA

Иерархия немного сложна:

(упрощено ради вопроса)

Корневой элемент

abstract ElementRoot имеет член link

public abstract class ElementRoot implements Serializable {

    protected String link;

    @XmlElement(name = "link")
    public String getLink() {
        return link;
    }

    public void setLink(String link) {
        this.link = link;
    }

}

Оболочка

abstract Wrapper расширяет ElementRoot и имеет член totalSize

public abstract class Wrapper<T> extends ElementRoot {

    protected int totalSize;

    protected List<T> collection = new ArrayList<>();

    @XmlElement
    public int getTotalSize() {
        return totalSize;
    }

    public void setTotalSize(int totalSize) {
        this.totalSize = totalSize;
    }

    public abstract List<T> getCollection();
}

Держатель

Держатель расширяет ElementRoot

@XmlRootElement(name = "holder")
@XmlType(propOrder = {"name", "elements"})
public class Holder extends ElementRoot {

    private String name;

    private Elements elements;

    // setters and getters not annotated
}

Элементы

Elements расширяет Wrapper и содержит коллекцию элементов.

import java.util.Collection;
import javax.xml.bind.annotation.*;

@XmlRootElement(name = "elements)
public class Elements extends Wrapper {

    @Override
    @XmlElement(name="element")
    public Collection<Element> getElements() {
        return elements;
    }

    // No setter, to add getElements().add(element)
}

Элемент

Элемент расширяет ElementRoot

@XmlRootElement(name = "element")
@XmlType(propOrder = {"id", "name"})
public class Element extends ElementRoot {

     private Integer id;

     private String name;

     // setters and getters no annotated

}

ОКРУЖАЮЩАЯ СРЕДА

Я использую java 7:

JAXB-api 2.2.7
MOXy 2.5.0

person ssedano    schedule 20.06.2013    source источник
comment
Я добавил несколько классов моделей к вашему вопросу на основе вашего описания. Как вы аннотируете эти классы? Также, где должен появиться элемент datastore во входных данных XML?   -  person bdoughan    schedule 20.06.2013
comment
datastore остался от оригинала, я упростил иерархию. Спасибо!   -  person ssedano    schedule 21.06.2013


Ответы (1)


Ошибка в EclipseLink JAXB (MOXy) для этого варианта использования, связанного с абстрактным свойством getCollecion. Мы открыли следующую ошибку, которую вы можете использовать, чтобы отслеживать наш прогресс по этой проблеме:

ВРЕМЕННОЕ РЕШЕНИЕ

Оболочка

Мы можем использовать @XmlAccessorType(XmlAccessType.NONE), чтобы обрабатывать только аннотированные поля/свойства (см.: http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html).

import java.util.*;
import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.NONE)
public abstract class Wrapper<T> extends ElementRoot {

    protected int totalSize;

    protected List<T> collection = new ArrayList<>();

    @XmlElement
    public int getTotalSize() {
        return totalSize;
    }

    public void setTotalSize(int totalSize) {
        this.totalSize = totalSize;
    }

    public abstract List<T> getCollection();

}

Элементы

Поскольку @XmlAccessorType наследуется подклассами, мы укажем XmlAccessType.PUBLIC, чтобы вернуть все в нормальное состояние. Примечание. Я предполагаю, что метод getElements() в вашем вопросе должен был быть getCollection().

import java.util.*;
import javax.xml.bind.annotation.*;

@XmlRootElement(name = "elements")
@XmlAccessorType(XmlAccessType.PUBLIC_MEMBER)
public class Elements extends Wrapper {

    @Override
    @XmlElement(name="element")
    public List<Element> getCollection() {
        return collection;
    }

    // No setter, to add getElements().add(element)
}
person bdoughan    schedule 21.06.2013