JAXB отображает фрагмент XML как фрагмент в другом XML-документе

Есть ли при использовании JAXB предпочтительный (или лучший) способ взять фрагмент XML из документа, а затем включить этот фрагмент в другой документ? Преобразование одной схемы в другую. У кого-нибудь есть ссылка на этот метод? Я пытался найти несколько способов сделать это, но большинство результатов поиска приводило к простому упорядочению и рассортировке.

У меня есть несколько исходных XML-документов, содержащих XML-фрагменты, которые я хочу включить в XML-документ вторичного назначения. Фрагмент назначения будет выглядеть точно так же, как исходный фрагмент. Пространства имен различаются как для исходного, так и для целевого XML-документа, главным образом потому, что схемы немного различались для одних и тех же тегов, но фрагмент был определен одинаково, за исключением того, что он находился в родительском пространстве имен (при создании объекта JAXB я хотел объекты Java для каждого пространства имен, потому что элементы назывались одинаково для разных данных и имели некоторые проблемы с попыткой использовать общую схему для фрагмента).

Для данного исходного XML-файла MyDoc (см. ниже) у меня есть XML-фрагмент вложенного документа, который я хочу включить в список вложенных документов в целевом XML-файле DestDoc. Attrib_1 имеет такое же имя в целевом документе, однако типы содержимого отличаются. Я пытаюсь взять поддокумент из MyDoc и включить в список поддокументов в DestDoc, как показано ниже. Поскольку вложенный документ — это тот же XML, мне просто нужно преобразовать его из mydoc/subdoc в destdoc/subdocs/subdoc.

Поскольку я начинаю с XML, я могу разобрать объекты MyDoc и получить объект вложенного документа. На этом этапе я мог бы упорядочить это во фрагмент XML, попытаться вставить его в родительские XML-элементы назначения в нужном месте, а затем отменить сортировку в качестве целевого объекта, чтобы добавить дополнительный контент или использовать средство сопоставления поддоков для перевода между mydoc/ объект subdoc и объект destdoc/subdoc, но тогда у меня будет объект, который зависит от двух схем. Если какая-либо из схем изменяется, это точка обслуживания. В конечном счете, после всех творческих аспектов DestDoc, я буду упорядочивать XML для ввода в другой процесс.

Обычный пример, который я нашел, если имена MyDoc и DestDoc не имеют смысла, представьте Bookstore как DestDoc, вложенные документы в виде книг, вложенный документ в виде книги и MyDoc в виде BookInfo. Attrib_1 может быть book_id с разными значениями для источника и назначения, а attrib_6 может быть суммарным количеством вложенных документов.

Исходный XML:

<MyDoc xmlns="http://www.test.com/xsd/mydoc">
  <attrib_1>987</attrib_1>
  <attrib_2>bcd</attrib_2>
  <subdoc>
    <attrib_3>a1</attrib_3>
    <attrib_4>b1</attrib_4>
  </subdoc>
</MyDoc>

XML-файл назначения:

<DestDoc xmlns="http://www.test.com/xsd/destdoc">
  <attrib_1>abc</attrib_1>
  <attrib_5>123</attrib_5>
  <attrib_6>456</attrib_6>
  <subdocs>
    <subdoc>
      <attrib_3>a1</attrib_3>
      <attrib_4>b1</attrib_4>
    </subdoc>
  </subdocs>
</DestDoc>

person jrsdev    schedule 09.12.2013    source источник


Ответы (2)


С дополнительными требованиями, указанными в ваших комментариях к ответу Даниэля Кека, вам, вероятно, лучше всего использовать этот подход:

  1. Разместите старые данные в экземпляре объекта определенного типа (как определено в старой схеме).
  2. Создайте пустой экземпляр объекта нового типа, который вы создаете в новой схеме.
  3. Заполните поля нового объекта любыми соответствующими полями из объекта старых данных, которые вы хотите, а также любыми новыми данными, которые вы предпочитаете.
  4. Маршалируйте новые данные, используя валидатор, определенный новой схемой.

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

person Bill Horvath    schedule 11.12.2013
comment
Спасибо. Ваши мысли совпадают с моими мыслями, хотя я думаю, что вместо интерфейса я буду использовать средство отображения объектов, использующее отражение, чтобы мне не нужно было привязывать средство отображения к схеме или изменять сгенерированные JAXB классы. Объекты точно такие же, за исключением пространства имен/пакета. Я просто хотел убедиться, что не упустил ни одного предпочтительного способа через существующие API. - person jrsdev; 11.12.2013

Попробуйте выполнить маршалинг в DOM:

   DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
   dbf.setNamespaceAware(true);
   DocumentBuilder db = dbf.newDocumentBuilder();
   Document doc = db.newDocument();

   m.marshal(jaxbElement, doc);

А затем используйте просто старомодный адоптированный узел.

person Daniel Kec    schedule 09.12.2013
comment
Ваше предложение является хорошим из всего, что я могу сказать. Я исследовал идею в течение нескольких часов. Я не осознавал, что у DOM есть возможность принять такое, однако позвольте мне добавить еще одно требование, которое, возможно, мне следовало добавить в исходный вопрос. Вложенный документ в DestDoc на самом деле представляет собой список вложенных документов (‹поддокументы›‹поддокумент›....‹/поддокумент›‹/поддокументы). В результате я буду собирать объекты JAXBSource (вложенные документы и атрибуты), а затем упорядочивать их оттуда. Имеет ли смысл переключаться между JAXB и DOM с точки зрения обработки и производительности? - person jrsdev; 11.12.2013
comment
Поскольку я не получил полного дерева DOM (родительская структура для DestDoc) при обработке поддокументов, могу ли я даже выполнить внедрение в дерево DOM так, как вы предлагаете? По сути, у меня есть фрагмент документа subdoc. Поскольку вложенные документы являются дочерними элементами DestDoc, attrib_1, attrib_5 и attrib_6 не существуют, когда я создаю вложенные документы. attrib_6, например, может быть количеством вложенных документов или других сводных данных, содержание которых я не узнаю до окончания обработки вложенных документов. - person jrsdev; 11.12.2013
comment
Еще раз спасибо за предложение. Мне это нравится, и я буду использовать его в будущем. - person jrsdev; 11.12.2013