当前位置: 首页 > 知识库问答 >
问题:

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

贡烨烁
2023-03-14

情况

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

问题所在

我使用的模型对象是在较旧的系统中很好地建立起来的,并且XML文档的模式是相当新的。由于我们的许多代码依赖于模型对象的结构,所以我们不想重新构造它们。下面是我正在处理的结构差异类型的一个简化示例:

示例数据模型树

项目

  • 说明
  • 成本
  • ...

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

地址

  • 街道
  • 城市
  • ...

SaleTransaction(*这是正在翻译的东西)

  • 买方(人)
  • 卖家(人)
  • 已售出项目[](列表)
  • 交换的项目[](列表)
  • 交易地点(地址)

XML文档结构示例

交换

  • 类型
  • 各方
    • Party_Contact_Ref
      • 类型
      • contact_id
      • 类型
      • total_amount_exchanged
        • 类型
        • owning_party_contact_ref_id
        • Exchange_use_type
        • 联系人
          • ID
          • 类型

          交换类型:“现款出售易货组合现款与易货”

          联系人类型:[人员地址]

          汇兑明细类型:“现金汇兑易货汇兑”

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

          如果我正在处理的对象图需要一些转换以便在XML文档中使用,那么我的工具是XMLAdapter。但是在本例中,我认为使用JAXB XML适配器不是一个可行的解决方案,原因有三。

          1. 模型图中的对象对应的XML元素也是数据相关的。我相信所有XmlAdapter到类/属性的映射都是固定的。
          2. 使用XMLAdapters似乎不可能实现多对一或一对多的解决方案。MOXy有一个有趣的扩展,但它需要固定的属性映射。
          3. 据我所知,XmlAdapters处理单个对象,无法获取被封送/解封的整个图的上下文。

          这个问题

          我相信这类问题相当普遍,那么你是如何处理的呢?有没有一种方法可以用标准工具来处理这个问题?

          我想出的

          如果它是有趣的,下面是我想出的可能的方法:

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

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

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

          我对这三种解决方案中的任何一种都不是超级兴奋,但我最偏爱第一种。

共有3个答案

雍志文
2023-03-14

很抱歉,我没有给你一个直接的答案,但我还不能以我的名誉来评论,所以这是我的“答案”。

我肯定会尝试Altova XML Spy及其代码生成特性。我试过了,非常有用。我不知道它是否能起到相反的作用,但由于它还具有数据库连接性和其他一些东西,我确信尝试一下并玩玩它不会有什么坏处。

他们还有一个叫做MapForce的应用程序(在地图数据库中,而不是地理信息系统中),我从来没有尝试过,但是我希望他们会非常有用。

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

颛孙镜
2023-03-14

如果我正在处理的对象树需要一些转换以便在XML文档中使用,那么我的工具是XMLAdapter。但是在这种情况下,我认为使用JAXB XML适配器不是一个可行的解决方案。据我所知,XmlAdapters处理单个对象,无法获取被封送/解封的整个树的上下文。

通常,XmlAdapter是无状态的,但您可以在包含状态的Marshaller/Unmarshaller上指定一个实例XmlAdapter。这也许就是你需要的全部。

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

您在封送器/反封送器上指定的实例将用于配置相应类的位置:

@XmlJavaTypeAdpater(YourAdapter.class)

有关更多信息

  • http://blog.bdoughan.com/2011/09/mixing-nesting-and-references-with.html
怀飞掣
2023-03-14

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

您可以尝试Dozer为任何具有类似命名字段的类,它将使用反射来进行映射。我在过去使用过这种方法,但我的模式看起来更类似于域对象,因此可能没有那么大的帮助。

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

 类似资料:
  • 是否有任何JAXB绑定可以告诉JAXB代码生成器将Java类生成为,而不必在XSD中将相应的XML类型标记为? 情况如下: > 我在xsd中定义架构: 我使用内联JAXB绑定(“inline”==“直接在模式中”)来指示应该生成JAXB类的包(): 我使用内联JAXB绑定为我的每个复杂类型(在本例中、和)指示实现类的名称: 我从模式生成JAXB类。这导致: 我自己编写类: 使用这两个类层次结构这样

  • 我正忙于将pre-build文件添加到我的项目中,以减小每个体系结构的Apk文件大小。 这篇文章在他的中添加了以下内容: 库提供以下文件: 我应该将文件按原样放置在我的文件夹中(不为每个体系结构创建文件夹),还是应该将其添加到文件夹中? <罢工> 以上哪一项 我应该使用文件来支持所有的体系结构吗? <罢工> 在这篇文章中,他还谈到了版本控制,这是必要的吗(我的应用程序是live的,我不想搞砸版本控

  • 我有一个golang结构,其中包含对其他结构的引用。有没有一种自动化的方法来生成。结构中的原始文件? 例如: 应生成:

  • 问题内容: 给出如下结果 但是我需要从输出中删除xml声明,我该怎么做 问题答案: 您是否看到了Transformer使用的OutputKeys?特别是OMIT_XML_DECLARATION。 请注意,删除标头在XML 1.0中有效,但是会丢失字符编码数据(尤其如此),这可能非常重要。

  • 问题内容: 我们如何在Java中生成非常大的随机数?我说的是10000位数吗?我知道我们必须使用BigInteger,但是我们该怎么做呢?做这样的事情最有效的方法是什么?请提供一个小例子。谢谢。 问题答案: 嗯,一种方法是转到Random.org并下载二进制随机文件之一。这些文件是由大气噪声生成的,因此非常随机。我在国际象棋引擎中将其用于Zobrist键。 或者你可以去 这会给你你想要的。在此示例