【问题标题】:Howto generate Java Enum from XML Schema with JAXB?如何使用 JAXB 从 XML 模式生成 Java 枚举?
【发布时间】:2011-08-27 06:10:25
【问题描述】:

我正在使用 maven 插件 maven-jaxb2-plugin 从 XSD Schema 文件生成 POJO。 这工作正常。唯一让我感到困扰的是,xml 模式枚举没有映射到 Java 枚举类型中。

我的 maven 插件正在从我称为 schemachooser.xsd 的文件中生成 java pojos

schemachooser.xsd

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:sch="http://www.ascc.net/xml/schematron" 
targetNamespace="http://schema.something" elementFormDefault="qualified"
version="1.0" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jaxb:extensionBindingPrefixes="xjc" jaxb:version="1.0">

<xs:annotation>
    <xs:appinfo>
        <jaxb:globalBindings generateIsSetMethod="true" fixedAttributeAsConstantProperty="true">
            <xjc:serializable />
        </jaxb:globalBindings>
        <jaxb:schemaBindings>
           <jaxb:bindings node="//xsd:element[@name='ElementName']/xsd:simpleType">
               <jaxb:typesafeEnumClass name="MyEnumType" />
           </jaxb:bindings>
        </jaxb:schemaBindings>
    </xs:appinfo>
</xs:annotation>

<xs:include schemaLocation="myNormalSchema.xsd" />

</schema>

它会生成文件,但不会生成“新”枚举类“MyEnumType”。我是不是用错了绑定?

【问题讨论】:

    标签: java enums schema jaxb


    【解决方案1】:

    如果您想将 JAXB 注释与 XML 模式分开,那么您需要使用 JAXB 绑定文件:

    bindings.xml

    <jaxb:bindings 
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
        xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
        jaxb:extensionBindingPrefixes="xjc"
        version="2.1">
        <jaxb:globalBindings generateIsSetMethod="true" fixedAttributeAsConstantProperty="true">
            <xjc:serializable />
        </jaxb:globalBindings>
        <jaxb:bindings schemaLocation="myNormalSchema.xsd">
            <jaxb:bindings node="//xs:element[@name='ElementName']/xs:simpleType">
                   <jaxb:typesafeEnumClass name="MyEnumType" />
            </jaxb:bindings>
       </jaxb:bindings>
    </jaxb:bindings>
    

    myNormalSchema.xsd

    以下是根据您的问题进行逆向工程的示例 XML 架构:

    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema 
        targetNamespace="http://www.example.com" 
         xmlns="http://www.example.com" 
         xmlns:xs="http://www.w3.org/2001/XMLSchema">
    
        <xs:element name="ElementName">
            <xs:simpleType>
                <xs:restriction base="xs:string">
                    <xs:enumeration value="MY_ENUM_1"/>
                    <xs:enumeration value="MY_ENUM_2"/>
                </xs:restriction>
            </xs:simpleType>
       </xs:element>
    
        <xs:element name="Root">
            <xs:complexType>
                <xs:sequence>
                    <xs:element ref="ElementName"/>
                </xs:sequence>
            </xs:complexType>
        </xs:element>
    
    </xs:schema>
    

    XJC 通话

    xjc -extension -d out -b bindings.xml myNormalSchema.xsd
    

    MyEnumType

    其中一个生成的类是一个名为MyEnumType 的枚举。

    package com.example;
    
    import javax.xml.bind.annotation.XmlEnum;
    import javax.xml.bind.annotation.XmlType;
    
    @XmlType(name = "")
    @XmlEnum
    public enum MyEnumType {
    
        MY_ENUM_1,
        MY_ENUM_2;
    
        public String value() {
            return name();
        }
    
        public static MyEnumType fromValue(String v) {
            return valueOf(v);
        }
    
    }
    

    Root 类也是使用isSet 方法生成的:

    package com.example;
    
    import java.io.Serializable;
    import javax.xml.bind.annotation.XmlAccessType;
    import javax.xml.bind.annotation.XmlAccessorType;
    import javax.xml.bind.annotation.XmlElement;
    import javax.xml.bind.annotation.XmlRootElement;
    import javax.xml.bind.annotation.XmlType;
    
    
    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "", propOrder = {
        "elementName"
    })
    @XmlRootElement(name = "Root")
    public class Root
        implements Serializable
    {
    
        @XmlElement(name = "ElementName", required = true)
        protected MyEnumType elementName;
    
        public MyEnumType getElementName() {
            return elementName;
        }
    
        public void setElementName(MyEnumType value) {
            this.elementName = value;
        }
    
        public boolean isSetElementName() {
            return (this.elementName!= null);
        }
    
    }
    

    示例

    【讨论】:

    • 我需要对所有此类元素进行绑定吗?有没有办法为所有受枚举限制的字符串切换此修改?我在提供的模式中有 287 次出现,我无法修改它们。
    • 拯救了我的一天,但是驴子的巨大痛苦......应该有更好的方法。
    猜你喜欢
    • 2017-01-23
    • 2015-09-02
    • 1970-01-01
    • 2016-12-13
    • 2018-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-24
    相关资源
    最近更新 更多