Различение между нулевым и пустым списком в xml / jaxb - PullRequest
0 голосов
/ 09 мая 2019

В Java, Json и т. Д. Вы можете различать нулевой и пустой список в свойствах объекта.В XML они обычно представлены как «без элемента с таким именем свойства», поэтому различие потеряно.Таким образом, при маршалинге и демаршаллинге Java-объекта у свойства всегда будет пустой список.

Это различие особенно актуально при описании изменений, например, в протоколе на основе xml, где «ноль» будет означать «не изменять», а «пустой список» будет означать «установить пустой список».

Таким образом, вопрос заключается в том, как определить xsd и потенциально xjb (jaxb bindings) для определения протокола, который может различать два.

Тривиальный xsd для такого объекта:

<complexType name="Object">
    <sequence>
        <element type="xs:string" name="id" minOccurs="0" maxOccurs="unbounded"/>
    <sequence>
</complexType>

Это создаст Java-код, подобный

public List<String> getIds() {
    if (ids == null) {
        ids = new ArrayList<>();
    }
    return this.ids;
}

Так что, очевидно, getIds никогда не вернет ноль.Но здесь это совершенно очевидно, потому что нет двух разных xmls, пустой или пустой список будет маршалирован до

<Object>
<Object>

Итак, моей первой идеей было использование nillable:

<complexType name="Object">
    <sequence>
        <element type="xs:string" name="id" 
            minOccurs="0" maxOccurs="unbounded" nillable="true"/>
    <sequence>
</complexType>

Тогда пустой список будет описан выше, но null может быть описан как

<Object>
    <id xsi:nil="true">
<Object>

Однако jaxb этого не соблюдает, он создаст тот же код, что и выше.

Мой следующий идентификатор должен был использовать тип списка xsd:

<xs:simpleType name="IdListType">
    <xs:list itemType="xs:string"/>
</xs:simpleType>

С объектом, описанным как

<complexType name="Object">
    <sequence>
        <element type="IdListType" name="ids" minOccurs="0"/>
    <sequence>
</complexType>

Тогда ноль мог быть записан как

<Object>
<Object>

И пустой список как

<Object>
    <ids></ids>
<Object>

Однако jaxb просто создает тот же код, что и выше, он даже не создает Java-класс для IdListType.

Так что мне осталось использоватьсложный список данных типа, подобный этому

<complexType name=IdListType>
    <sequence>
        <element name="id" type="xs:string" minOccurs="0" maxOccurs="unbounded">
    </sequence>
</complexType>

и объект xsd, как указано выше.Это сработало бы, но создавало много кода, как в сгенерированном коде, так и на проводе в протоколе.

Поэтому мой вопрос: есть ли более простой способ, возможно, такой, который быjaxb уважать различия в одном из перечисленных xsds?

...