JAXB使用元素名称代替类型时产生POJO

时间:2019-02-02 18:26:37

标签: spring xsd jaxb pojo

我想用jaxb从xsd生成pojos。 但是xsd由外部供应商提供,其中元素具有有意义的名称, 但类型是怪异。只是一个例子:

<xs:element name="PersonAddress" type="PerAdr" />

<xs:complexType name="PerAdr">
    <xs:sequence>
        <xs:element name="street" type="xs:string" minOccurs="1" maxOccurs="unbounded" />
        <xs:element name="house" type="xs:string" minOccurs="1" maxOccurs="unbounded" />
    </xs:sequence>
</xs:complexType>

所以生成的类被称为PerAdr。 如何使其生成其名称为元素名称而不是类型的类,因此在这种情况下将生成类PersonAddress。

我有一个庞大的xsd,所以想一个聪明的方法,而不仅仅是在.xjb文件中写几百行

1 个答案:

答案 0 :(得分:0)

我并不是JAXB的专业人士。但是我查看了JAXB规范(在这里:http://download.oracle.com/otn-pub/jcp/jaxb-2.0-fr-oth-JSpec/jaxb-2_0-fr-spec.pdf),发现了以下内容:


派生于架构的Element类的特征来自 上的“元素声明架构组件”的属性术语 第349页,如下所示:

  • 所生成的Java Element类的名称是从 使用XML名称到Java标识符的元素声明 {name} 类名的映射算法。

  • 每个生成的Element类必须扩展Java值类javax.xml.bind.JAXBElement<T>。下一个项目符号指定 用于泛型参数T的模式派生Java类名称。

  • 如果元素声明的 {类型定义}

    • 匿名 :第二个项目符号的通用参数T设置为表示派生的架构类型,该类表示按指定生成的匿名类型定义 在第6.7.3节中。
    • 命名: 第二个项目符号的通用参数T设置为表示元素声明的 {type definition} 的Java类。

因此,可以得出以下结论:一旦有了具有命名XSD类型的XSD元素,就必须处理代表该类型并以此名称命名的Java类。这是合乎逻辑的。毕竟,您可能具有相同全局类型的不同XSD元素。这是默认的映射。

但是,JAXB允许(XML模式的)自定义,您可以使用这些自定义来覆盖某些内容。例如,您可以修改XSD类型生成的Java类的名称,例如:

<xs:complexType name="USAddress">
  <xs:annotation> <xs:appinfo>
    <jaxb:class name="MyAddress" />
  </xs:appinfo></xs:annotation>
  <xs:sequence>...</xs:sequence>
  <xs:attribute name="country" type="xs:string"/>
</xs:complexType>

因此,结果Java类将被命名为 USAddress ,而不是MyAddress。这看起来像是解决问题的方法,但是要利用它,您将需要修改XSD中的每个类型定义,这听起来很艰巨,因为您的架构很大。

那么,你能做什么?

首先,您需要确保架构中的每个XSD元素及其(全局定义的)类型都是唯一对应的。如果碰巧有几个具有相同类型的不同XSD元素,则显然类型名称不能等于所有它们。在这种情况下,如果您不喜欢原始类型名称,则只需手动编辑该架构,并为这些类型提供不同的名称,以使其更适合您。

只有当关系XSD元素<->其XSD类型是唯一的时,任何自动化都是可能的!在这种情况下,您可以从元素名称中派生类型名称:使其相同或添加例如T前缀:TPersonAddress

通常称为重构,并且可以自动完成。问题是如何?

好吧,由于XSD是XML,因此您可以编写 XSLT脚本,以进行必要的转换。但这可能不是那么简单,因为您将不得不对模式进行一些解析。也就是说,要识别那里的每个XSD元素并找到相应的XSD类型,然后在两个位置都更改类型名称。或者,您可以如上所述在每个XSD类型的定义中插入那些自定义指令(<jaxb:...>元素)。我不知道对这些东西进行编程将花费多少。无疑,这将取决于创建索引(使用<xsl:key>构造)并对其进行迭代。


或者,我可以建议您使用非传统的方法。我们开发了一个名为FlexDoc/XML的工具。本质上,它是XML文件到任何东西的转换器。使用一些与XSLT相似的模板对转换进行编程。

最初的想法是将类似于XSLT的方法扩展到通过各种API提供的任何一种基于Java的数据源。例如,我们有一个类似的产品叫做 模仿标准Javadoc的FlexDoc/Javadoc。但是后来我们意识到XML本身也是一个充满各种繁重任务的好领域,而XSLT则太轻量级。例如,由数百个XSD和WSDL文件生成易于导航的单个文档,为此,我们现在拥有两个模板集:XSDDocWSDLDoc。 (我们还在为JSON模式进行类似的工作。)

使用FlexDoc/XML可以创建一个满足您需要的模板(重新命名那些XSD类型)。这可以在一个小时内完成,如果您最终购买了“ FlexDoc / XML SDK”许可证,我们将为您完成。 (人们通常购买SDK许可证来自定义XSDDoc / WSDLDoc模板。但是,它也可以等同地用作诸如您这样的任务的单独工具。)