从具有许多相同元素名称的XML模式生成时如何避免巨大的Java文件

时间:2015-11-12 14:41:47

标签: java xml eclipse web-services jaxb

我正在使用非常大的Web服务架构(40,000行,5,000个元素)编写Web服务客户端。这个模式是外部提供的,即我无法改变它。

我使用JAXB为客户端生成Java类。默认情况下,所有类都生成一个Java文件,最终有500,000行。

对于我的IDE(Eclipse)来说,这是一个很大的问题,即使有4GB内存也会挂起并崩溃。

我可以通过生成单独的Java文件来解决此问题,但架构中的许多实体具有相同的名称。当所有Java类都在同一个包中生成时,有超过500个名称冲突。

如果我要使用jaxb绑定来避免这些冲突,我将不得不手动编写超过500个绑定定义。

如果我可以自动将XML层次结构映射到java包中会非常方便,但我已经看到了一个例子。

我无法透露架构本身,但这里有一个小例子来说明问题:

<xs:element name="top">
    <xs:element name="customer">
        <xs:element name="name">
            ...
        </xs:element>
        <xs:element name="address">
            ...
        </xs:element>
        <xs:element name="employee">
            <xs:element name="name">
                ...
            </xs:element>
            <xs:element name="address">
                ...
            </xs:element>
        </xs:element>
    </xs:element>
    <xs:element name="provider">
        <xs:element name="product">
            <xs:element name="name">
                ...
            </xs:element>
        </xs:element>
        <xs:element name="name">
            ...
        </xs:element>
        <xs:element name="address">
            ...
        </xs:element>
    </xs:element>
</xs:element>

所需的结果将是Java类,如:

com.mycompany.generated.Top
com.mycompany.generated.top.Customer
com.mycompany.generated.top.customer.Name
com.mycompany.generated.top.customer.Address
com.mycompany.generated.top.customer.Employee
com.mycompany.generated.top.customer.employee.Name
com.mycompany.generated.top.customer.employee.Address
...
com.mycompany.generated.top.Provider
...

我怎样才能做到这一点?

编辑:原始xsd(与此处提供的代码段不同)完全有效,但它会单独定义每个元素。例如。尽管有许多类型称为具有相同定义的地址,但每个类型都在其元素标记之间定义,而不是重新使用类型。这就是它如此之大的一个原因,以及为什么有这么多相同的类。为了使它更复杂,我还发现了具有相同名称和不同细节的类型定义。

我不需要填充WS中的所有元素,因此我的主要目标是在不费吹灰头的情况下成功生成代码。

我不愿意在本地更改模式以重复使用类型定义,因为我希望将来的更改需要一次又一次地应用相同的修改。

1 个答案:

答案 0 :(得分:1)

您可以使用以下命令生成单独的Java类:

<jaxb:globalBindings localScoping="toplevel"/>

但是这仍然会让你有500个类名自定义。你可以去暴力破解或写一个XJC插件来处理它。我认为蛮力比写插件要快。

但是,我不会在不同的套餐中进行分类。 JAXB有许多包级别的功能,如果你在不同的包中解析相同命名空间的类,它可能会失败/出错。所以我只做<jaxb:class name="CustomerName"/>个自定义。

我还考虑编写一个XSLT转换,它会自动生成模式中的绑定文件。应该不难。