2016-08-25 4 views
0

Используя это (демо) схему, я генерация Java объектов с JAXB:Как использовать XmlAdapter для сопоставления сложных типов XML с объектами Java в классах, генерируемых схемой?

<xsd:complexType name="someType"> 
    <xsd:sequence> 
     <xsd:element name="myOtherType" type="otherType" maxOccurs="unbounded" /> 
    </xsd:sequence> 
</xsd:complexType> 

<xsd:complexType name="otherType"> 
    <!-- ... --> 
</xsd:complexType> 

Этот класс получает генерируется:

@XmlType 
public class SomeType { 

    @XmlElement(name = "myOtherType") 
    OtherType myOtherType; 

} 

Но я хотел бы использовать интерфейсы вместо реализации в моем JAXB- генерируемых объектов.

Итак, я пишу этот интерфейс:

public interface OtherTypeInterface { 
    // .... 
} 

И я позволил генерируемый OtherType класс реализовать с помощью связывания файла:

<jxb:bindings node="//xs:complexType[@name='otherType']"> 
    <inheritance:implements>com.example.OtherTypeInterface</inheritance:implements> 
</jxb:bindings> 

До сих пор так хорошо:

public class OtherType implements OtherTypeInterface { 

    // ... 

} 

Но мне нужен объект SomeType, чтобы использовать этот интерфейс, а не реализацию OtherType. Как предложено in the unofficial JAXB guide в разделе 3.2.2. Используйте @XmlJavaTypeAdapter, я хотел бы использовать самодельный адаптер XML для отображения OtherType его интерфейс, и наоборот:

public class HcpartyTypeAdapter extends XmlAdapter<OtherType, OtherTypeInterface> { 

    @Override 
    public OtherTypeInterface unmarshal(OtherType v) throws Exception { 
     return v; 
    } 

    @Override 
    public OtherType marshal(OtherTypeInterface v) throws Exception { 
     return (OtherType) v; 
    } 

} 

Но это выглядит как отображение в сложный тип XML в моем файле связывания со следующей конфигурацией не большой нет-нет:

<jxb:globalBindings> 
    <xjc:javaType name="com.example.OtherTypeInterface" xmlType="ex:otherType" adapter="com.example.OtherTypeAdapter"/> 
</jxb:globalBindings> 

поколение терпит неудачу с этой ошибкой:

com.sun.istack.SAXParseException2; systemId: file:/.../bindings.xjb; lineNumber: 8; columnNumber: 22; undefined simple type "{ http://www.example.com }otherType".

с a bit of googling, я узнал, что я t, по-видимому, невозможно использовать XML-адаптеры для сложных типов в классах, генерируемых схемой. Тем не менее, если я вручную редактировать файлы использовать свой адаптер, он отлично работает:

public class SomeType { 

    @XmlElement(name = "myOtherType") 
    @XmlJavaTypeAdapter(OtherTypeAdapter.class) 
    @XmlSchemaType(name = "otherType") 
    OtherTypeInterface myOtherType; 

} 

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

Итак, мой вопрос: кто-нибудь знает обходное решение для использования XML-адаптеров для сопоставления сложных типов XML с объектами Java в генерируемых схемой классах, не прибегая к ручному редактированию кода?


Возможный ответ здесь: https://stackoverflow.com/a/1889584/946800. Я надеюсь, что с 2009 года кто-то, возможно, нашел способ решить эту проблему ...

ответ

0

плагин maven для добавления аннотаций к сгенерированным классам JAXB.

  <plugin> 
       <!-- this plugin is used to add annotation for the models --> 
       <groupId>org.jvnet.jaxb2_commons</groupId> 
       <artifactId>jaxb2-basics-annotate</artifactId> 
       <version>1.0.2</version> 
      </plugin> 

В .xjb привязок,

<jxb:bindings schemaLocation="sample.xsd"> 
    <jxb:bindings node="//xs:complexType[@name='otherType']"> 
     <annox:annotate target="field"> 
      <annox:annotate annox:class="@javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter" 
       value="com.example.OtherTypeAdapter.class" /> 
     </annox:annotate> 
    </jxb:bindings> 
</jxb:bindings>