Как маршалировать развернутую коллекцию в JAXB?

#java #jaxb #jaxb2

#java #jaxb #jaxb2

Вопрос:

Это мой класс:

 @XmlRootElement(name = "foo")
@XmlAccessorType(XmlAccessType.NONE)
public class Foo {
  @XmlElement
  public Collection getElements() {
    List elements = new ArrayList();
    elements.add(new Bar);
    elements.add(new Bar);
    return elements;
  }
}
  

Класс Bar также прост:

 @XmlType(name = "bar")
@XmlAccessorType(XmlAccessType.NONE)
public static final class Bar {
  @XmlElement
  public String getMessage() {
    return "hello, world!";
  }
}
  

Это то, что я получаю после маршалинга Foo :

 <foo>
  <elements xsi:type="foo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <message>hello, world!</message>
  </elements>
  <elements xsi:type="foo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <message>hello, world!</message>
  </elements>
</foo>
  

В то время как я ожидаю получить:

 <foo>
  <bar>
    <message>hello, world!</message>
  </bar>
  <bar>
    <message>hello, world!</message>
  </bar>
</foo>
  

Что я должен исправить?

Ответ №1:

Вам нужно будет аннотировать elements свойство с помощью @XmlElement(name="bar") :

 @XmlRootElement(name = "foo")
@XmlAccessorType(XmlAccessType.NONE)
public class Foo {
  @XmlElement(name="bar")
  public Collection getElements() {
    List elements = new ArrayList();
    elements.add(new Bar);
    elements.add(new Bar);
    return elements;
  }
}
  

Комментарии:

1. Но я хочу использовать их имена из их @XmlType аннотаций. Я не хочу дублировать это объявление в Foo классе… Возможно? Более того, в примере из реальной жизни я не знаю, как их зовут.

2. @yegor256 — Вместо значения @XmlType аннотации вы можете использовать значение @XmlRootElement аннотации. Если значения коллекции участвуют в иерархии наследования, вы можете использовать @XmlElementRef аннотацию: blog.bdoughan.com/2010/11 /. … Если они не связаны, вы можете использовать @XmlAnyElement(lax=true) аннотацию: blog.bdoughan.com/2010/08 /…