Bezdepbonusu7Программирование: статьи и ответы

Вопрос

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

Автор вопроса: jrsdevОтветов: 2

Есть ли при использовании 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>

javaxmljaxbmarshallingunmarshalling

Ответы

Ответ 1 · Bill Horvath

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

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

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

Ответ 2 · рейтинг 2 · Daniel Kec

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

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

   m.marshal(jaxbElement, doc);

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

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы