2013-12-09 121 views
1

使用JAXB,是否有从文档中获取XML片段并将该片段包含在另一个文档中的首选(或最佳)方法?从一个模式映射到另一个模式。有没有人有对该方法的参考?我试图找到一些这样做的方法,但大多数搜索结果只是编组和解组。JAXB将XML片段映射为另一个XML文档中的片段

我有多个XML源文档,其中包含要包含在辅助目标XML文档中的XML片段。目标片段看起来与源片段完全相同。源文件和目标文件的命名空间不同,主要是因为相同标记的模式略有不同,但片段被定义为相同,只是它在父命名空间中(使用JAXB对象生成,我希望将包的分隔每个名称空间的Java对象,因为元素对不同的数据命名相同,并且有一些问题试图为片段使用通用模式)。

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

由于我从XML开始,我可以对MyDoc对象解组并获取子目录对象。在这一点上,我可以将它们编码为XML片段,尝试将其插入到正确位置的目标XML父元素中,然后解组为目标对象以添加其他内容,或者使用subdoc映射器在mydoc/subdoc对象和destdoc/subdoc对象,但我会有一个依赖于两个模式的对象。如果任一模式改变,这是一个维护点。最终,在DestDoc的所有创建方面之后,我将编组XML以输入到另一个进程。

如果名称MyDoc和DestDoc没有意义,将Bookstore设想为DestDoc,subdocs为书籍,subdoc为book,MyDoc为BookInfo,则会发现一个常见示例。 Attrib_1可能是book_id,其源和目标的值不同,而attrib_6可能是subdoc的总计数。

源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> 

回答

0

随着丹尼尔·Kec的的回答您的意见中规定的其他要求,你可能最好关闭使用这种方法:

  1. 解组旧数据变成它的一个对象实例的特殊 类型(定义旧模式)
  2. 在新模式下创建您正在创建的新类型的空对象实例。
  3. 使用您希望从旧数据对象获得的任何相应字段以及您喜欢的任何新数据填充新对象的字段。
  4. 使用由新模式定义的验证程序来统计新数据。

作为一种替代方案,您可以定义一个类来实现由新模式指定的接口,以及封装旧类型的实例,以将特定方法实现委派给哪个实例。然后,您可能(大概)将旧类型的对象(在解组之后)作为参数传递给所讨论的类的构造函数。然后你可以编出新班级的实例。

+1

谢谢。你的想法是正确的,尽管我认为不是一个接口,而是使用一个使用反射的对象映射器,这样我就不必将映射器绑定到模式或修改JAXB生成的类。对象除了名称空间/包之外完全相同。我只是想确保我没有忽略任何通过现有API的首选方式。 – jrsdev

2

尝试编组到DOM:

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

    m.marshal(jaxbElement, doc); 

然后只使用老式采用节点。

+0

你的建议是一个很好的从我可以告诉的一切。我一直在研究这个想法几个小时。我没有意识到DOM有这样的能力,但是,让我提出另一个要求,也许我应该在原来的问题中加入。 DestDoc中的子目录实际上是一个子目录列表( .... jrsdev

+0

因为我在处理子目录时没有获得完整的DOM树(DestDoc的父结构),所以我甚至可以按照您的建议将其采纳到DOM树中吗?基本上,我有一个subdoc的文档片段。由于子目录是DestDoc的子项,因此在创建子目录时,attrib_1和attrib_5和attrib_6不存在。例如,attrib_6可能是一个subdocs或其他摘要数据的计数,其内容直到处理子目录结束时才会知道。 – jrsdev

+0

再次感谢您的建议。我喜欢它,并将在未来使用它。 – jrsdev