Как обрабатывать разные версии файлов XSD в одном приложении Java?

Факты

В моем Java-приложении я должен обрабатывать XML-файлы с разными версиями схемы (xsd-файлы) одновременно. Содержимое файлов XML мало изменилось между различными версиями, поэтому я хотел бы использовать в основном один и тот же код для его обработки и просто делать некоторые различия в зависимости от версии используемой схемы.

Текущее решение

Сейчас я анализирую XML-файлы с помощью SAX-парсера и моего собственного ContentHandler игнорирование версии схемы и просто проверка наличия тегов, которые мне нужны для обработки.

Возможная альтернатива

Мне бы очень хотелось использовать JAXB для генерации классов для разбора файлов XML. Таким образом, я мог бы удалить все жестко закодированные строки (константы) из моего кода Java и обработать сгенерированные классы.

Вопросы)

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

Прогресс

Я скомпилировал версии схемы для разных пакетов v1, v2 и v3. Теперь я могу создать Unmarshaller сюда:

JAXBContext jc = JAXBContext.newInstance( 
    v1.Root.class, v2.Root.class, v3.Root.class );
Unmarshaller u = jc.createUnmarshaller();

Сейчас u.unmarshal( xmlInputStream ); дает мне Root класс из пакета, соответствующий схеме файла XML.

Далее я попытаюсь определить interface для доступа к общим частям схем. Если вы сделали что-то подобное раньше, пожалуйста, дайте мне знать. В то же время я читаю спецификации JAXB...

1 ответ

Решение

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

Далее идет доступ к данным. Вы не говорите, почему вы используете три разные схемы. Единственная рациональная причина - развивающаяся спецификация данных (т.е. схемы представляют версии 1, 2 и 3 тех же данных). Если это не ваша причина, то вам нужно переосмыслить свой дизайн.

Если вы пытаетесь поддерживать развивающуюся спецификацию данных, то вам нужно ответить на вопрос "как мне поступить с отсутствующими данными". Есть несколько ответов на этот вопрос: один - поддерживать несколько версий кода. С рефакторингом общей функциональности это неплохая идея, но она может легко стать непригодной.

Альтернативой является использование единой кодовой базы и какого-либо объекта- адаптера, который включает ваши правила. И если вы пойдете по этому пути, JAXB - неправильное решение, так как оно связано со схемой. Возможно, вы сможете использовать разрешающий XML->Java-конвертер: я верю, что XStream будет работать, и я знаю, что версия 1.1 Практического XML будет работать (с тех пор, как я ее написал) - хотя вам придется создавать его самостоятельно.

Другая, лучшая альтернатива, в зависимости от сложности схемы, состоит в разработке набора объектов, которые используют XPath для извлечения данных. Я бы, вероятно, реализовал использование "главного" объекта, который содержит выражения XPath для каждого поля, в каждом варианте схемы. Затем создайте легкие объекты-обертки, которые содержат DOM-версию вашего экземпляра документа, и используйте XPath, соответствующий схеме. Обратите внимание, что это ограниченный доступ только для чтения.

Другие вопросы по тегам