Как обрабатывать разные версии файлов XSD в одном приложении Java? - PullRequest
12 голосов
/ 10 ноября 2009

Факты

В моем 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 Ответ

6 голосов
/ 10 ноября 2009

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

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

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

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

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

...