Java JAXB将XML片段映射为另一个XML文档中的片段

Java JAXB将XML片段映射为另一个XML文档中的片段,java,xml,jaxb,marshalling,unmarshalling,Java,Xml,Jaxb,Marshalling,Unmarshalling,使用JAXB,是否有一种首选(或最佳)方法从文档中获取XML片段,然后将该片段包含在另一个文档中?从一个模式到另一个模式的映射。有人提到过这种方法吗?我试图找到一些方法来做到这一点,但大多数搜索结果只会导致编组和解编组 我有多个XML源文档,其中包含要包含在第二个目标XML文档中的XML片段。目标片段看起来与源片段完全相同。源XML文档和目标XML文档的名称空间都不同,主要是因为相同标记的模式略有不同,但片段的定义是相同的,只是它位于父名称空间中(对于JAXB对象生成,我希望每个名称空间的Jav

使用JAXB,是否有一种首选(或最佳)方法从文档中获取XML片段,然后将该片段包含在另一个文档中?从一个模式到另一个模式的映射。有人提到过这种方法吗?我试图找到一些方法来做到这一点,但大多数搜索结果只会导致编组和解编组

我有多个XML源文档,其中包含要包含在第二个目标XML文档中的XML片段。目标片段看起来与源片段完全相同。源XML文档和目标XML文档的名称空间都不同,主要是因为相同标记的模式略有不同,但片段的定义是相同的,只是它位于父名称空间中(对于JAXB对象生成,我希望每个名称空间的Java对象都有包分离,因为元素对于不同的数据命名相同,并且在尝试使用片段的公共模式时存在一些问题)

对于MyDoc的给定源XML(见下文),我有一个子文档XML片段,我想将其包含在DestDoc目标XML中的子文档列表中。Attrib_1在目标文档中的名称相同,但内容类型不同。我正试图从MyDoc中获取子文档,并将其包含在DestDoc中的子文档列表中,如下所示。由于子文档是相同的XML,我只需要从mydoc/subdoc转换为destdoc/subdoc/subdoc

因为我是从XML开始的,所以我可以解组MyDoc对象并获得subdoc对象。在这一点上,我可以将其整理成一个XML片段,尝试将其插入到目标XML父元素的正确位置,然后作为目标对象解组以添加其他内容或使用子文档映射器进行翻译在mydoc/subdoc对象和destdoc/subdoc对象之间设置了e,但是我会有一个依赖于这两个模式的对象。如果其中一个模式发生更改,这是一个维护点。最终,在完成destdoc的所有创建方面之后,我将整理成XML,以便输入到另一个进程

我发现的一个常见示例是,如果MyDoc和DestDoc的名称没有意义,那么可以将Bookstore视为DestDoc,子文档视为books,子文档视为book,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>

987
卡介苗
a1
b1
目标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>

abc
123
456
a1
b1

尝试封送到DOM:

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

   m.marshal(jaxbElement, doc);

然后只使用老式的adopt node。

根据您对Daniel Kec答案的评论中指定的附加要求,您最好使用以下方法:

  • 将旧数据解组到其特定对象的对象实例中 类型(在旧模式中定义)
  • 在新模式下创建新类型的空对象实例
  • 使用您希望从旧数据对象获得的任何相应字段以及您喜欢的任何新数据填充新对象的字段
  • 使用新模式定义的验证器封送新数据

  • 作为替代方案,您可以定义一个类,该类实现新模式指定的接口,并封装旧类型的实例,将特定方法实现委托给该实例。然后(大概)传递旧类型对象(在其被解组后)作为所讨论类的构造函数的参数。然后,您可以整理出新类的实例。

    从我所知道的一切来看,您的建议都是很好的。我已经研究了几个小时的想法。我没有意识到DOM有能力采用这样的方法,但是,让我加入另一个可能是我自己的要求应该在原始问题中添加。DestDoc中的子文档实际上是一个子文档列表(……因为我没有得到完整的DOM树(DestDoc的父结构)在处理子文档时,我甚至可以按照您建议的方式将其应用到DOM树中吗?本质上,我有一个子文档的文档片段。由于子文档是DestDoc的子文档,attrib_1和attrib_5,并且在创建子文档时attrib_6不存在。例如,attrib_6可能是子文档或其他摘要数据的计数nt,直到处理子文档结束我才知道。再次感谢你的建议。我喜欢它,将来也会使用它。谢谢。你的想法正是我所想的,尽管我认为我将使用一个使用反射的对象映射器,而不是一个接口,这样我就不必将映射器绑定到模式或修改JAXB生成的类。除了名称空间/包之外,对象完全相同。我只是想确保我没有忽略任何通过现有API的首选方式。