Ситуация
Мне нужно поддерживать создание 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 для поддержки нескольких схем с небольшими вариациями без кучи дублирования кода?
- Есть ли другая комбинация технологий, на которую я должен смотреть?
ИЗМЕНИТЬ
Решение, приведенное ниже от Blaise, отлично работало для большинства наших схем, которые были лишь незначительным переводом друг друга с общими одинаковыми данными. Однако мы столкнулись с проблемой в тех случаях, когда имеет смысл использовать наследование с именами пакетов для управления версиями. Например:
com.company.xml.schema.v1.ElementA
com.company.xml.schema.v2.ElementA
(где v2.ElementA расширяет v1.ElementA)
Использование MOXy OXM в этом случае натыкается на ошибку, и обходной путь можно найти здесь (с решением, предоставленным Blaise, не менее!)