Как получить значения minOccurs / maxOccurs из XSD в Java с использованием JAXB?
Мое приложение вызывает веб-сервис, и я сгенерировал классы Java из WSDL/XSD с помощью плагина maven-jaxb2-plugin. Некоторое время веб-сервисы работали нормально, но недавно у меня возникла проблема с маршалингом объекта в XML:
[org.xml.sax.SAXParseException: cvc-complex-type.2.4.d: Invalid content was found starting with element 'ns1:TheFooAndBarThing'.
No child element '{"http://www.myschemanamespace.xyz/v1":BarId}' is expected at this point.]
Часть XSD выглядит так:
<xs:complexType name="TheFooAndBarThing">
<xs:sequence>
<xs:element name="FooId" minOccurs="1" maxOccurs="1" type="nx:FooIdType"/>
<xs:element name="BarId" minOccurs="1" maxOccurs="100" type="nx:BarIdType"/>
</xs:sequence>
</xs:complexType>
Сгенерированный класс TheFooAndBarThing
выглядит так (удален Javadoc):
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "TheFooAndBarThing", propOrder = {
"fooId",
"barId"
})
public class TheFooAndBarThing {
@XmlElement(name = "FooId", required = true)
protected String fooId;
@XmlElement(name = "BarId", required = true)
protected List<String> barId;
public String getFooId() {
return fooId;
}
public void setFooId(String value) {
this.fooId = value;
}
public List<String> getBarId() {
if (barId == null) {
barId = new ArrayList<String>();
}
return this.barId;
}
}
Мне потребовалось некоторое время и кофе, чтобы выяснить настоящую проблему. Моя ошибка заключалась в том, что я поставил более 100 BarId
элементы в моем списке.
Итак, вот мой вопрос:
Как я могу получить значение maxOccurs/minOccurs из XSD в свой Java-код, чтобы я мог использовать его в качестве значения max/min при построении списка элементов?
2 ответа
Краткий ответ: нет простого пути.
Производные от схемы классы больше не имеют ссылки на исходную схему. Даже если вы используете что-то в качестве XSOM или что-то еще для анализа исходной схемы, вы не сможете найти соответствующие конструкции XML-схемы для проверки.
Лучший способ решить эту проблему - написать собственный плагин XJC (я написал немало).
Когда XJC компилирует схему, сначала создается модель, затем так называемая схема (предварительно обработанный код), а затем визуализируется код. Модель по-прежнему содержит информацию об исходных конструкциях XML-схемы, поэтому вы можете найти всю необходимую информацию о min/maxOccurs.
Проблема только в том, что у вас не всегда есть отображение 1:1 между конструкциями схемы и свойствами классов, производных от схемы. Иногда несколько элементов отображаются на одно свойство. Там огромное количество исключений и особых случаев. Вы можете заставить это работать для простых случаев, все же. Во всяком случае, задача не из легких.
Использование может попробовать JAXB-Facets.
Вот пример установки определенных значений для minoccurs и maxoccurs:
@MinOccurs(value = 0)
@MaxOccurs(value = 100)
private List<String> test;