JAXB Типы проблемы - PullRequest
       15

JAXB Типы проблемы

3 голосов
/ 26 апреля 2009

У меня есть xsd, который выглядит так (фрагмент):

<xs:complexType name="IDType">
  <xs:choice minOccurs="1" maxOccurs="2">
    <xs:element name="FileID"    minOccurs="0" maxOccurs="1" type="an..35" />
    <xs:element name="IDNumber1" minOccurs="0" maxOccurs="1" type="an..35" />
    <xs:element name="Number"    minOccurs="0" maxOccurs="1" type="an..35" />
    <xs:element name="PNumber"   minOccurs="0" maxOccurs="1" type="an..35" />
    <xs:element name="SS"        minOccurs="0" maxOccurs="1" type="an..35" />
    <xs:element name="Player"    minOccurs="0" maxOccurs="1" type="an..35" />
    <xs:element name="Prior"     minOccurs="0" maxOccurs="1" type="an..35" />
    <xs:element name="BIN"       minOccurs="0" maxOccurs="1" type="an..35" />
    <xs:element name="Mutual"    minOccurs="0" maxOccurs="1" type="an..35" />
  </xs:choice>
</xs:complexType>
<xs:simpleType name="an..35">
  <xs:restriction base="an">
    <xs:maxLength value="35" />
  </xs:restriction>
</xs:simpleType>

<xs:simpleType name="an">
   <xs:restriction base="xs:string">
     <xs:pattern value="[ !-~]*" />
   </xs:restriction>
</xs:simpleType>

По какой-то причине генерируется код Java:

<code>@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "IDType", propOrder = {
    "fileID"
})
public class PatientIDType {
    @XmlElementRefs({
        @XmlElementRef(name = "FileED", namespace = "http://www.surescripts.com/messaging", type = JAXBElement.class),
        @XmlElementRef(name = "IDNumber1", namespace = "http://www.surescripts.com/messaging", type = JAXBElement.class),
        @XmlElementRef(name = "Number", namespace = "http://www.surescripts.com/messaging", type = JAXBElement.class),
        @XmlElementRef(name = "PNumber", namespace = "http://www.surescripts.com/messaging", type = JAXBElement.class),
        @XmlElementRef(name = "SS", namespace = "http://www.surescripts.com/messaging", type = JAXBElement.class),
        @XmlElementRef(name = "Plaer", namespace = "http://www.surescripts.com/messaging", type = JAXBElement.class),
        @XmlElementRef(name = "Prior", namespace = "http://www.surescripts.com/messaging", type = JAXBElement.class),
        @XmlElementRef(name = "BIN", namespace = "http://www.surescripts.com/messaging", type = JAXBElement.class),
        @XmlElementRef(name = "Mutual", namespace = "http://www.surescripts.com/messaging", type = JAXBElement.class)
    })
    protected List<JAXBElement<String>> fileID;
    /**
     * Gets the value of the fileID property.
     * 
     * <p>
     * This accessor method returns a reference to the live list,
     * not a snapshot. Therefore any modification you make to the
     * returned list will be present inside the JAXB object.
     * This is why there is not a <CODE>set</CODE> method for the fileID property.
     * 
     * <p>
     * For example, to add a new item, do as follows:
     * <pre>
     *    getFileID().add(newItem);
     * 
* * *

* Объекты следующих типов разрешены в списке * {@link JAXBElement} {@ code <} {@ link String} {@ code>} * {@link JAXBElement} {@ code <} {@ link String} {@ code>} * {@link JAXBElement} {@ code <} {@ link String} {@ code>} * {@link JAXBElement} {@ code <} {@ link String} {@ code>} * {@link JAXBElement} {@ code <} {@ link String} {@ code>} * {@link JAXBElement} {@ code <} {@ link String} {@ code>} * {@link JAXBElement} {@ code <} {@ link String} {@ code>} * {@link JAXBElement} {@ code <} {@ link String} {@ code>} * {@link JAXBElement} {@ code <} {@ link String} {@ code>} * / открытый список > getFileID () { if (fileID == null) { fileID = new ArrayList > (); } вернуть this.fileID; }

Почему класс генерируется так, а не просто как строковый массив? Я действительно не хочу создавать JAXBElements каждый раз, когда я хочу что-то создать?

Как он может генерировать классы для каждого из типов, которые просто представляют строку или что-то в этом роде?

Заранее спасибо,

Ian

Ответы [ 3 ]

6 голосов
/ 03 мая 2009

Этот код генерируется, потому что ваш сложный тип, IDType, содержит выбор с maxOccurrence больше, чем один, здесь:

Содержимое этих списков - это элементы с разными именами , но с одинаковым типом . Это не имеет эквивалента в стандартных объектно-ориентированных моделях. Затем JAXB использует класс JAXBElement, чтобы обойти это: JAXBElement оборачивает простой объект, содержащий данные, и присваивает ему QName.

Таким образом, вы можете прочитать из этого списка и однозначно написать в список, указав:

  • Объект данных (в вашем случае String, поскольку все ограничения из String представлены в виде строки Java)
  • A JAXBElement, чей метод getValue() возвращает строку

Спецификация JAXB содержит довольно подробные и достаточно сложные объяснения того, как обращаться с повторяющимися вариантами и повторяющимися последовательностями. Обратите внимание, что если ваша последовательность содержит объекты разных типов, а также разные имена, вы получите List .

Это было длинное объяснение, теперь вот несколько вариантов:

  • Если вы можете изменить схему, поместите элемент обертки вокруг 8 элементов, скажем, «Обертка». Оболочка будет содержать один выбор элементов; Затем заставьте IDType содержать последовательность элементов Wrapper с minOccurs = 1 и maxOccurs = 2.
  • Создайте себе несколько вспомогательных функций для быстрого создания элементов JAXB. JAXB помещает класс Factory в целевой пакет, который может вам помочь - например, он содержит ссылки на пространство имен Schema и т. Д.
4 голосов
/ 22 декабря 2011

Ваш класс ObejctFActory должен иметь createMethod для значений thosr, что-то вроде

@XmlElementDecl(namespace = "http://www.surescripts.com/messaging", name = "SocialSecurity", scope = PatientIDType.class)
public JAXBElement<String> createPatientIDTypeSocialSecurity(String value) {
    return new JAXBElement<String>(_PayerIDTypeSocialSecurity_QNAME, String.class, PatientIDType.class, value);
}
1 голос
/ 27 апреля 2009

Если вы используете реализацию Sun JAXB, вы можете попробовать скомпилировать с включенным режимом xjc: simple. См. Документацию по упрощенное связывание для примера. Должно повернуть

public class PatientIDType {
    protected List<JAXBElement<String>> fileID;
}

в

public class PatientIDType {
    String fileID;
    ...
}

Вам необходимо скомпилировать схему с помощью файла настроек привязки. См. блог Kohsuke для примера того, как это сделать.

...