2010-04-26 2 views
9

Я использую xjc для генерации Java-классов из схемы XML, а следующая - отрывок из XSD.XML-схема для Java-классов с XJC

<xs:element name="NameInfo"> 
    <xs:complexType> 
    <xs:sequence> 
     <xs:choice> 
     <xs:element ref="UnstructuredName"/> <!-- This line --> 
     <xs:sequence> 
      <xs:element ref="StructuredName"/> 
      <xs:element ref="UnstructuredName" minOccurs="0"/> <!-- and this line! --> 
     </xs:sequence> 
     </xs:choice> 
     <xs:element ref="SomethingElse" minOccurs="0"/> 
    </xs:sequence> 
    </xs:complexType> 
</xs:element> 

По большей части сгенерированные классы являются хорошо, но для вышеупомянутого блока я хотел бы получить что-то вроде:

public List<Object> getContent() { 
    if (content == null) { 
    content = new ArrayList<Object>(); 
    } 
    return this.content; 
} 

со следующим комментарием над ним:

* You are getting this "catch-all" property because of the following reason: 
* The field name "UnstructuredName" is used by two different parts of a schema. See: 
* line XXXX of file:FILE.xsd 
* line XXXX of file:FILE.xsd 
* To get rid of this property, apply a property customization to one 
* of both of the following declarations to change their names: 
* Gets the value of the content property. 

У меня есть разместил комментарий в конце двух строк.

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

Я искал и нашел this page, является ли внешняя настройка тем, что я хочу сделать? В основном я работаю с созданными классами, поэтому я не совсем знаком с процессом, который генерирует эти классы. Простой пример «настройки свойств» был бы замечательным! Альтернативный метод генерации классов Java был бы прекрасен, пока схема все еще может быть использована.

EDIT: Я должен уточнить, что два UnstructuredName действительно являются одним и тем же элементом.

ответ

1

Существенная проблема заключается в том, что у вас есть <xs:sequence>, состоящий из <xs:choice>, который переводит на Java на «List вещей». Структура типа Java не является достаточно гибкой, чтобы представлять ее лучше.

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

Альтернативный метод, который я использовал в прошлом, заключается в том, чтобы сначала передать схему с помощью простого преобразования XSLT, переустановив компоненты в нечто более удобное для JAXB, сохраняя при этом все те же структуры, что и документы в действительности , Таким образом, вы можете «изменить» схему без изменения оригинала.

+0

Я не совсем уверен, как перестановке элементы могут помочь в этом случае. Если я могу внутренняя «последовательность» в другой элемент, эта проблема будет решена? Возможно ли это с преобразованием? Если я выполняю какое-то преобразование, мне понадобится преобразовать его в структуру, которая мне нравится, а затем выполнить другое преобразование обратно в ее исходную структуру? – nevets1219

2

У меня была та же проблема. Я переключился на xmlbeans и axis. XMLBeans может скомпилировать вашу схему без проблем и без головной боли. JaxB не может справиться с этим. Чтобы JaxB справился с этим, вы можете немного изменить свою схему.

<xs:sequence> 
      <xs:choice> 
    <!-- changed the following line --> 
      <xs:element name="UnstructuredTop" type="UnstructuredName"/> 
    <!-- end of change --> 
      <xs:sequence> 
       <xs:element ref="StructuredName"/> 
       <xs:element ref="UnstructuredName" minOccurs="0"/> 
      </xs:sequence> 
      </xs:choice> 
      <xs:element ref="SomethingElse" minOccurs="0"/> 
    </xs:sequence> 

Тогда JaxB будет различать два и не выворачивать.

Однако ваша ситуация подобна моей ситуации. Изменение схемы не могло быть и речи. Поэтому я пошел с xmlBeans и осью (которая sux).

5

Вы можете также использовать привязку настройки под названием <xjc:simple />:

<?xml version="1.0" encoding="UTF-8"?> 
<jxb:bindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb" 
       xmlns:xs="http://www.w3.org/2001/XMLSchema" 
       xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" 
       jxb:version="2.0"> 
     <jxb:globalBindings> 
      <xjc:simple /> 
     </jxb:globalBindings> 
</jxb:bindings> 

Пожалуйста, однако, посоветовал, что это конкретный поставщик (который использует что-то другое, чем XJC хотя;))

Подробнее here

0

Я создал класс обертки, чтобы решить эту проблему:

List<JAXBElement<?>> contentList = address.getContent(); 
if (contentList != null && contentList.size() > 0) { 
    Address4JaxbMula address4JaxbMula = new Address4JaxbMula(contentList); 

... }

...

public static class Address4JaxbMula { 
    public CountryCodeType countryCode; 
    public AddressFixType addressFix; 
    public String addressFree; 

    public Address4JaxbMula(List<JAXBElement<?>> contentList) { 
     if (contentList != null && contentList.size() > 0) { 
      for (JAXBElement<?> content : contentList) { 
       Object value = content.getValue(); 
       if (value.getClass().isAssignableFrom(CountryCodeType.class)) { 
        countryCode = (CountryCodeType) content.getValue(); 
       } else if (value.getClass().isAssignableFrom(AddressFixType.class)) { 
        addressFix = (AddressFixType) content.getValue(); 
       } else { 
        addressFree = (String) value; 
       } 
      } 
     } 
    } 

}