Как создать аннотацию XMLElementWrapper с помощью xjc и настраиваемой привязки
Я использую JAXB и xjc для компиляции моей XML-схемы в классы Java. Я не хочу вручную редактировать сгенерированные классы. У меня есть XML-схема, как это:
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="items">
<xs:complexType>
<xs:sequence>
<xs:element ref="item" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
XJC генерирует класс Items
который содержит только список Item
объекты. Есть ли шанс пропустить класс Items
и иметь список Item
объекты непосредственно в Root
учебный класс?
Я знаю, что это можно сделать с @XMLElementWrapper
аннотации, но я не знаю, как сказать xjc, чтобы создать такой.
Спасибо за любые предложения!
С наилучшими пожеланиями, Маркус
2 ответа
Бьярне Хансен разработал плагин для xjc, который смог позаботиться об этом. К сожалению, ссылка на оригинальную реализацию теперь не работает. Тем не менее, есть проект Дмитрия Кацубо на github, основанный на оригинальном коде Бьярне с некоторыми дополнительными улучшениями.
→ https://github.com/dmak/jaxb-xew-plugin
(Просто для справки: исходная ссылка, теперь мертвая: http://www.conspicio.dk/blog/bjarne/jaxb-xmlelementwrapper-plugin)
Сначала давайте разберем вашу схему так, чтобы не было сгенерированных внутренних классов:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:element name="root" type="Root" />
<xs:complexType name="Root">
<xs:sequence>
<xs:element name="items" type="Items" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="Items">
<xs:sequence>
<xs:element name="item" type="xs:string" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:schema>
Вы все равно получите дополнительные классы, но не все в одном файле. Теперь вы хотите добавить раздел в свою сборку, чтобы использовать jaxb-xew-plugin
, Я использую Maven, поэтому для меня это выглядит так:
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.8.2</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<args>
<arg>-no-header</arg>
<arg>-Xxew</arg>
<arg>-Xxew:instantiate lazy</arg>
<arg>-Xxew:delete</arg>
</args>
<plugins>
<plugin>
<groupId>com.github.jaxb-xew-plugin</groupId>
<artifactId>jaxb-xew-plugin</artifactId>
<version>1.0</version>
</plugin>
</plugins>
</configuration>
</execution>
</executions>
</plugin>
Если вы начнете использовать пространства имен, чтобы у ваших сгенерированных классов были имена пакетов, не используйте -Xxew:delete
флаг, так как есть ошибка, которую я недавно исправил, когда он удалял объекты, которые он не должен. В качестве альтернативы вы можете получить код из github и использовать его как 1.1-SNAPSHOT.
Когда я делаю это, я получаю сгенерированный код, который, я думаю, вы ищете:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Root", propOrder = {
"items"
})
public class Root {
@XmlElementWrapper(name = "items", required = true)
@XmlElement(name = "item")
protected List<String> items;
public List<String> getItems() {
if (items == null) {
items = new ArrayList<String>();
}
return items;
}
public void setItems(List<String> items) {
this.items = items;
}
}