Как получить значения 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;
Другие вопросы по тегам