2009-04-26 12 views
2

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

<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, который получает генерируется:

@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); 
    * </pre> 
    * 
    * 
    * <p> 
    * Objects of the following type(s) are allowed in the list 
    * {@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 >} 
    */ 
    public List<JAXBElement<String>> getFileID() { 
     if (fileID == null) { 
      fileID = new ArrayList<JAXBElement<String>>(); 
     } 
     return this.fileID; 
    } 

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

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

Спасибо заранее,

Ian

+0

Замечание: ваш фрагмент схемы, кажется, отсутствует (или не указан для правильного отображения?). – StaxMan

ответ

6

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

< хз: выбор MinOccurs = "1" MaxOccurs = "2" >

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

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

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

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

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

  • Если вы можете изменить схему, поставить элемент обертку вокруг 8 элементов, скажем, «обертка».Обертка будет содержать единственный выбор элементов; Затем make IDType содержит последовательность элементов Wrapper с minOccurs = 1 и maxOccurs = 2.
  • Создайте себе вспомогательные функции, чтобы быстро создать JAXBElements. JAXB ставит класс Factory в вашей целевой пакет, который может помочь вам - например, он содержит ссылки на пространство имен схемы и т.д.
+0

Отличный ответ. Спасибо. К сожалению, это XSD, поставляемый снаружи, поэтому мне придется пойти со вторым вариантом. Не мой любимый, но он, безусловно, будет работать – 2009-05-18 23:32:29

1

Если вы используете реализацию Sun JAXB, вы можете попробовать скомпилировать с XJC: включен простой режим. См. Документацию по адресу simplified binding. Он должен превратить

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

и

public class PatientIDType { 
    String fileID; 
    ... 
} 

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

+0

Я пробовал добавить эту привязку, но все же результат тот же. Я что-то упускаю? [код] [/ код] – 2009-04-26 22:43:27

+0

Странно, что он не делал что-нибудь. Изменил ли он какой-либо из других классов Java? Наиболее примечательной является плюрализация имен коллекций. Вы используете XJC прямо как xjc -extension simpleBinding.schemalet abc.xsd ? – deverton

+0

Было несколько изменений, но ничего значительного. Я называю это с помощью ant с атрибутом extension = "true" – 2009-04-28 01:18:33

3

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

@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); 
}