Использование JAXB для поддержки схем с незначительными изменениями

Ситуация

Мне нужно поддерживать создание XML-документов на основе схем, которые незначительно отличаются друг от друга. В частности, схемы, которые мне нужно поддерживать, основаны на отраслевых стандартах, которые незначительно меняются со временем, и поставщики могут создавать свои собственные адаптированные версии этих схем.

Проблема

В качестве решения я намеревался использовать JAXB 2 (из Metro) с наследованием. Я ожидал, что структура пакета будет выглядеть примерно так:

    com.company.xml.schema.v1
    com.company.xml.schema.v2
    com.company.xml.schema.v2.vendorxyz

Где классы в пакете v2 будут просто расширять классы в пакете v1 и переопределяться по мере необходимости. К сожалению, этот план оказался невозможным, поскольку подклассы не могут перезаписывать аннотации в родительских классах (см. здесь). Например, если атрибут в схеме был переименован между версиями, то класс элемента v2 должен был бы полностью переименовать элемент, не наследуя от v1.

Так что это оставляет мне только два варианта, насколько я могу судить

Вариант 1

Создать "базовый" пакет для каждого типа схемы, аннотировать классы элементов в этом пакете с @XmlAccessorType(XmlAccessType.NONE), и удалить все другие аннотации. Затем в каждом версионном пакете создайте классы, которые являются подклассами соответствующего класса в "базовом" пакете, и добавьте все необходимые аннотации. Это решение дает мне небольшую помощь в области наследования, но дублирование кода огромно, и поддерживать его будет непросто.

Вариант 2

Не использовать JAXB. Мне действительно не нравится это решение, поскольку я также хотел бы работать с JAX-RS/JAX-WS.

Вопросы

  • Как я должен использовать JAXB для поддержки нескольких схем с незначительными вариациями без дублирования кода?
  • Есть ли другая комбинация технологий, на которую я должен обратить внимание?

EDIT

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

com.company.xml.schema.v1.ElementA
com.company.xml.schema.v2.ElementA

(где v2.ElementA расширяет v1.ElementA)

Использование MOXy's OXM в этом случае наталкивается на ошибку, и обходной путь можно найти здесь (с решением, предоставленным Blaise, не менее!)

12
задан Terence 26 February 2012 в 22:14
поделиться