Как разделить подэлементы <xsd: choice /> на отдельные свойства Collection с помощью JAXB? - PullRequest
4 голосов
/ 12 августа 2011

У меня есть следующий XSD фрагмент от Продавца, я не могу изменить способ, которым он указан:

<xsd:element name="navmap">
  <xsd:complexType>
    <xsd:choice minOccurs="0" maxOccurs="unbounded">
      <xsd:element ref="navitem"/>
      <xsd:element ref="debug"/>
    </xsd:choice>
    <xsd:attribute name="focus" type="xsd:string" use="optional"/>
  </xsd:complexType>
</xsd:element>

Прямо сейчас без настроек он генерирует следующий код

@XmlElements({
        @XmlElement(name = "navitem", type = Navitem.class),
        @XmlElement(name = "debug", type = Debug.class)
    })
    protected List<Object> navitemOrDebug;

Я бы предпочел, чтобы он генерировал отдельный список для каждого типа, как показано ниже

@XmlElements({
        @XmlElement(name = "navitem", type = Navitem.class)
    })
    protected List<Navitem> navitems;

@XmlElements({
        @XmlElement(name = "debug", type = Debug.class)
    })
    protected List<Debug> debugs;

В моем файле .xjb есть следующее, которое переименовывает весь List, но я не могувыяснить, как их разделить.

<jxb:bindings node="//xsd:element[@name='navmap']//xsd:complexType//xsd:choice">
  <jxb:property name="contents" />
</jxb:bindings>

Как мне указать, что я хочу отдельный List или Set для каждого из типов во внешнем .xjb файле привязки?

Если я не могу этого сделать, как мне добавить <jaxb:annotation/> в файл .xsd, чтобы указать отдельные List или Set для каждого из типов?

Надеюсьне заботьтесь о заказе, заказ не важен в данном конкретном случае.

ПРИМЕЧАНИЕ: Я бы предпочел внешнее решение .xjb, я не хочу иметьчтобы отличить пользовательский .xsd от каждой новой версии, предоставляемой поставщиком, их слишком много.

Ответы [ 2 ]

2 голосов
/ 01 октября 2011

Как и было обещано, познакомьтесь с плагином Simplify .

Этот плагин позволяет упростить "сложные" свойства.Эти свойства часто генерируются из повторяющихся вариантов, таких как этот:

<xs:complexType name="typeWithReferencesProperty">
    <xs:choice maxOccurs="unbounded">
        <xs:element name="a" type="someType"/>
        <xs:element name="b" type="someType"/>
    </xs:choice> 
</xs:complexType>

...

<xs:complexType name="typeWithElementsProperty">
    <xs:choice maxOccurs="unbounded">
        <xs:element name="a" type="xs:string"/>
        <xs:element name="b" type="xs:int"/>
    </xs:choice> 
</xs:complexType>

По умолчанию XJC объединяет свойства, моделирующие несколько ссылок или элементов в одной.

@XmlElementRefs({
    @XmlElementRef(name = "a", type = JAXBElement.class),
    @XmlElementRef(name = "b", type = JAXBElement.class)
})
protected List<JAXBElement<SomeType>> aOrB;

...

@XmlElements({
    @XmlElement(name = "a", type = String.class)
    @XmlElement(name = "b", type = Integer.class),
})
protected List<Serializable> aOrB;

Эти сложные свойства необходимы для адекватного моделирования сложного содержимого схемы XML, то есть для поддержания порядка элементов в повторяемом выборе.К сожалению, они не идиоматичны как свойства бобов.Эти свойства являются «неоднородными» (в том смысле, что они хранят разные типы), что затрудняет работу с ними.

Однако, если порядок элементов незначителен, то есть вы можете житьс учетом того, что он изменится после повторной сортировки, структуры этих свойств могут быть упрощены: сложные свойства можно разделить на несколько простых свойств.

Плагин Simplify реализует эту задачу.Это позволяет упростить ваши сложные свойства.Плагин удалит комплексное свойство и вставит несколько более простых свойств вместо исходного (сложного) свойства.Таким образом, вы можете получить что-то вроде:

@XmlElement(name = "a", type = String.class)
protected List<String> a;
@XmlElement(name = "b", type = Integer.class)
protected List<Integer> b;

Или:

@XmlElement(name = "a")
protected List<SomeType> a;
@XmlElement(name = "b")
protected List<SomeType> b;

Или:

@XmlElementRef(name = "a", type = JAXBElement.class)
protected List<JAXBElement<SomeType>> a;
@XmlElementRef(name = "b", type = JAXBElement.class)
protected List<JAXBElement<SomeType>> b;

Зависит от настройки.

плагин будет выпущен в JAXB2 Основы 0.6.3, теперь доступен как снимок из этого хранилища .

0 голосов
/ 30 сентября 2011

Насколько я знаю, на данный момент вы не можете (с XJC из JAXB RI).Теоретически возможно написать плагин, который изменяет модель XJC.

Но вы должны знать, что два отдельных однородных свойства debug и navitem не равны одному гетерогенному свойству navitemOrDebug.Т.е. вы получите другой порядок элементов, если вы удалите и маршалируете один и тот же объект.

Однако во многих случаях это может иметь смысл.Пожалуйста, напишите вопрос здесь , я рассмотрю возможность его реализации.

...