从Java对象生成XML文档,其结构非常不同

时间:2012-07-05 19:14:44

标签: java xml design-patterns jaxb mapping

情况

我在Java中有一个复杂的模型对象图,需要来回翻译成XML文档。 XML文档模式的对象图结构与模型的对象树截然不同。这两者是可以互换的,但翻译需要大量的上下文驱动逻辑,其中使用父/子关系。

问题

我正在处理在旧系统中已经建立的模型对象,而XML文档的模式是相当新的。由于我们的许多代码都依赖于模型对象的结构,因此我们不希望对它们进行重构。以下是我正在处理的结构差异类型的简化示例:

  

示例数据模型树

     

项目

     
      
  • 描述
  •   
  • 成本
  •   
  • ...
  •   
     

     
      
  • 名字
  •   
  • 姓氏
  •   
  • 地址
  •   
  • ...
  •   
     

地址

     
      
  •   
  •   
  • ...
  •   
     

SaleTransaction(*这是被翻译的东西)

     
      
  • 买方(人)
  •   
  • 卖方(人)
  •   
  • 已售物品[](清单)
  •   
  • 交换项目[](列表)
  •   
  • 交易地址(地址)
  •   
     

示例XML文档结构

     

交换

     
      
  • 类型
  •   
  • 缔约方   
        
    • party_contact_ref   
          
      •   
      • CONTACT_ID
      •   
    •   
  •   
  • 交换详情   
        
    •   
    • total_amount_exchanged
    •   
  •   
  • 产品   
        
    • 物品   
          
      •   
      • owning_party_contact_ref_id
      •   
      • exchange_use_type
      •   
    •   
  •   
  • 联系人   
        
    • 联系   
          
      • ID
      •   
      •   
    •   
  •   
     

交易所类型:[现金出售| BARTER |合并现金和大师]

     

联系人类型:[PERSON |地址]

     

交换详情类型:[现金交换| BARTER EXCHANGE]

SaleTransaction和Exchange之间的映射是可能的,而不是1-1。在该示例中,模型中的“买方”将映射到XML文档中的联系人和联系人引用元素。此外,“Item”元素的“owning_party_contact_ref_id”属性的值将通过查看SaleTransaction对象图中的几个不同值来确定。

如果我正在使用的对象图需要一些翻译才能在XML文档中使用,我的首选工具是XmlAdapter。但在这种情况下,我没有看到使用JAXB XML适配器作为可行的解决方案有三个原因。

  1. 模型图中对象的哪个XML元素也与数据相关。我相信所有XmlAdapter到类/属性映射都是固定的。
  2. 似乎无法使用XmlAdapter执行多对一或一对多的解决方案。 MOXy有一个interesting extension,但同样需要固定映射到属性。
  3. 据我所知,XmlAdapters使用单个对象,并且没有办法在整个图形的上下文中进行编组/解组。
  4. 问题

    我确定这种类型的问题相当常见,所以你如何处理呢?有没有办法用标准工具处理这个问题?

    我想出了什么

    如果它很有意思,以下是我提出的可行方法:

    #1 将对象图转换问题与XML生成问题分开。我有一个本土工具,可以帮助根据一些上下文对象生成对象图。我可以从XML模式创建JAXB类,然后依靠此工具根据模型对象的上下文生成这些类的对象。这样可以很好地从模型对象图生成XML文档,但不是相反。它还意味着依赖非标准工具,如果可能的话,我希望避免使用这些工具。

    #2 Go XmlAdapter疯狂并修改模型类以保留转换状态信息(例如,模型树中的此对象用于在XML文档中创建此元素)。这将使问题与JAXB的标准使用模型非常接近,但我认为开发,测试和维护将是一场噩梦。

    #3 像在#1中那样分离对象图问题,但是使用JDOM而不是JAXB。这将删除所有JAXB所需的类和映射,但需要构建另一个自定义工具来管理模型对象到DOM树映射。

    我对这三种解决方案中的任何一种都不是非常兴奋,但我最偏向于#1。

4 个答案:

答案 0 :(得分:2)

1是你最好的赌注恕我直言。编写映射代码很乏味但你应该抵制过于聪明的冲动。您使用的任何映射工具都需要配置,我敢打赌,与手工编写Java映射代码一样多。只需编写大量的单元测试。

您可以为具有相似命名字段的任何类尝试Dozer,它将使用反射来执行映射。我过去曾经使用过这个版本,但我的架构看起来与我的域对象更相似,所以它可能没那么有用。

为了使代码更加愉快,请使用您可以为JAXB找到的所有xjc插件,例如fluent-api和value-constructor。

答案 1 :(得分:1)

  

如果我正在使用的对象树需要一些翻译才能   在XML文档中使用,我的首选工具是XmlAdapter。在这   但是,我没有看到使用JAXB XML适配器作为可行的解决方案。   据我所知,XmlAdapters可以处理单个对象,但不能   有办法了解整棵树的背景   编组/解组。

通常XmlAdapter是无状态的,但您可以在包含州的XmlAdapter / Marshaller上指定Unmarshaller的实例。这可能就是您所需要的一切。

YourAdapter yourAdapter = new YourAdapter();
yourAdapter.setState(someState);
marshaller.setAdapter(yourAdapter);
unmarshaller.setAdapter(yourAdapter);

您在Marshaller / Unmarshaller上指定的实例将用于配置相应类的位置:

@XmlJavaTypeAdpater(YourAdapter.class)

了解更多信息

答案 2 :(得分:0)

对不起,我没有给你一个直截了当的回答,但我不能就我的声誉发表评论,所以这是我的“回答”。

我肯定会尝试Altova XML Spy而它是Code Generation features。我已经尝试过,并且非常有用。我不知道它能做的是反过来工作,但由于它还有Database connectivity和其他一些东西,我敢肯定它不会有任何伤害试试看,玩弄它。

他们还有另一个名为MapForce的应用程序(如在地图数据库中,而不是GIS),这是我从未尝试过的,但是我希望它们非常有用。

我希望您发现所有这些非常有用,并且您可以对此进行评论,并详细说明它对您(或不是)的帮助。

答案 3 :(得分:0)

如果您有xsd架构,使用castor之类的工具生成pojos非常有用。一旦你有包含生成的pojos的包,你可以使用dozer将你的“旧”对象模型映射到代表xml文档的pojos。然后你只需使用Marshaller将castor生成的对象转换为Stream,String等。