XJC不会在xs:union

时间:2016-05-17 16:17:50

标签: java enums xsd jaxb xjc

我有几个包含以下结构的XSD文件:

<xs:complexType name="SomeThing" abstract="false">
    <xs:sequence>
        <xs:element name="id" type="schema2:SomeIdTypeClass" minOccurs="1" maxOccurs="1"/>
        <xs:element name="myType" type="schema1:MyType" minOccurs="1" maxOccurs="1"/>
    </xs:sequence>
</xs:complexType>

<xs:simpleType name="MyType">
    <xs:union>
        <xs:simpleType>
            <xs:restriction base="xs:string">
                    <xs:enumeration value="APPLE"/>
                    <xs:enumeration value="ORANGE"/>
                    <xs:enumeration value="BANANA"/>
                </xs:restriction>
            </xs:simpleType>
            <xs:simpleType>
                <xs:restriction base="xs:string">
                <xs:pattern value="OTHER:[a-zA-Z_][a-zA-Z0-9_]*"/>
            </xs:restriction>
        </xs:simpleType>
    </xs:union>
</xs:simpleType>

我使用XJC命令在控制台上生成Java类,而不是maven或ant或任何其他构建工具。

除了这些枚举外,所有类似乎都可以生成。使用枚举类型的类仅将其作为字符串引用,例如 Something 类仅包含 MyType 作为字符串,而不是像我期望的那样包含ENUM。

在另一个文件中我有这样的东西,其中生成的枚举没有问题,并且引用类正在使用它作为枚举。

<xs:simpleType name="SizeType">
<xs:restriction base="xs:string">
        <xs:enumeration value="SMALL"/>
        <xs:enumeration value="MEDIUM"/>
        <xs:enumeration value="LARGE"/>
</xs:restriction>

我不想替换XSD文件,因为它们不是由我自己生成的,而且我有一些包含许多这些元素的文件。

我得出结论,我需要使用某种XJB绑定文件,但我无法弄清楚,我需要在那里写什么:

以下仅给出了错误&#34;导致目标节点太多&#34;

<jaxb:bindings version="2.0" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" 
jaxb:extensionBindingPrefixes="xjc">
    <jaxb:bindings schemaLocation="MySchema.xsd" node="/xs:schema">
        <jaxb:bindings node="//xs:simpleType[@name='MyType']/xs:union/xs:simpleType">
            <jaxb:typesafeEnumClass name="MyType"/>
        </jaxb:bindings>    
    </jaxb:bindings>
</jaxb:bindings>

添加 multiple =&#34; true&#34; 解决了这个问题,但仍未提供我想要的枚举。

编辑: 当我删除xs:union时,我有一个正常的xs:simpleType,如下所示:

<xs:simpleType name="MyType">
    <xs:restriction base="xs:string">
    <xs:pattern value="OTHER:[a-zA-Z_][a-zA-Z0-9_]*"/>
    <xs:enumeration value="APPLE"/>
    <xs:enumeration value="ORANGE"/>
    <xs:enumeration value="BANANA"/>
    </xs:restriction>             
</xs:simpleType>

然后按预期工作。如果我不需要,我仍然不想沿着那条路走下去并编辑模式。必须有一些方法。

2 个答案:

答案 0 :(得分:5)

好吧,我已经花了一些时间在这个主题上,我在Google上搜索了很多并做了一些测试。

简短答案:这不可能

详细答案:

This question是关于一个问题相同但更简单的人:他有一个union,其中包含一个simpleType(一个restriction和一些{{1} }),这很奇怪,因为enumeration是毫无意义的,但无论如何。

所以这个家伙被卡住了,this answer很有趣:

  

工会似乎没有得到很好的支持   https://jaxb.java.net/tutorial/section_2_2_10-Defining-a-Type-Union.html

     

如果可以修改架构,则可以提取枚举   将匿名简单类型转换为命名类型,然后在代码中使用   为此新类型生成的Java枚举。...

没有很好的支持...但是不如“一点也不”或“在某些情况下”?

不幸的是,链接断开了,但是由于我们的朋友The Internet ArchiveI pulled out我需要的信息:

  

在Java中,没有便捷的方式来表达简单的并集   类型。 JAXB编译器只需在任何位置插入Java的String类型   使用联合类型,并留给应用程序程序员   处理其余的。尽量避免使用union

这就是路的尽头,您被困住了。只要您的模式中存在xsd:union,就不会生成union类,并且始终会选择emum作为默认类型。

此外,我发现了这篇文章,Extend enumerated lists in XML schema。在某些解决方案中,作者主张使用String,但最终说:

  

需要union标签支持,有时工具中没有实现

最后,最好的解决方案可能是文章中的第一个:编辑原始架构以包括新的枚举值

答案 1 :(得分:0)

您需要使用以下绑定。

<jaxb:bindings version="2.0" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" 
jaxb:extensionBindingPrefixes="xjc">
<jaxb:bindings schemaLocation="MySchema.xsd" node="/xs:schema">
<jxb:bindings node="//xs:element[@name='MyType']">
            <jxb:property >
                <jxb:baseType name="java.lang.String"></jxb:baseType>
            </jxb:property>
        </jxb:bindings>
        </jxb:bindings>