JAXB enumeration with numeric values

后端 未结 3 1764
北恋
北恋 2020-12-14 08:51

I want to restrict input values like this


  
    

        
相关标签:
3条回答
  • 2020-12-14 09:20

    This code is more simpler way, works for me.

    @XmlEnum(value = Integer.class)
    public enum SomeEnum {
      @XmlEnumValue("0")
      Value1,
      @XmlEnumValue("1")
      Value2,
      @XmlEnumValue("2")
      Value3;
    }
    
    0 讨论(0)
  • 2020-12-14 09:27

    Here is my answer to a similar question that may help (see issue 2):

    • Enums don't match schema: problem with jaxb or xsd?

    There are a couple of enumeration values that are causing this issue. These issues can be overcome through the use of a JAXB external binding file (see below).

    Enum Issue #1 - Empty String

    Some of your enum values are empty string (""), which is causing a String rather than an enum property to be generated:

    <xs:enumeration value="">
        <xs:annotation>
            <xs:documentation>Blank</xs:documentation> 
        </xs:annotation>
    </xs:enumeration>
    

    Enum Issue #2 - Numeric String

    Some of the enum values are numbers which is causing a String rather than an enum property to be generated:

    <xs:enumeration value="6">
        <xs:annotation>
            <xs:documentation>6th grade</xs:documentation> 
       </xs:annotation>
    </xs:enumeration>
    

    Bindings File (bindings.xml)

    The following bindings file can be used to address the issues with the educationLevelType, the concepts here can be applied to all the problematic types:

    <jxb:bindings 
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
        version="2.1">
        <jxb:bindings schemaLocation="http://www.acf.hhs.gov/programs/cb/systems/nytd/nytd_data_file_format.xsd">
            <jxb:bindings node="//xs:simpleType[@name='educationLevelType']/xs:restriction/xs:enumeration[@value='6']">
                <jxb:typesafeEnumMember name="SIX"/>
            </jxb:bindings>
            <jxb:bindings node="//xs:simpleType[@name='educationLevelType']/xs:restriction/xs:enumeration[@value='7']">
                <jxb:typesafeEnumMember name="SEVEN"/>
            </jxb:bindings>
            <jxb:bindings node="//xs:simpleType[@name='educationLevelType']/xs:restriction/xs:enumeration[@value='8']">
                <jxb:typesafeEnumMember name="EIGHT"/>
            </jxb:bindings>
            <jxb:bindings node="//xs:simpleType[@name='educationLevelType']/xs:restriction/xs:enumeration[@value='9']">
                <jxb:typesafeEnumMember name="NINE"/>
            </jxb:bindings>
            <jxb:bindings node="//xs:simpleType[@name='educationLevelType']/xs:restriction/xs:enumeration[@value='10']">
                <jxb:typesafeEnumMember name="TEN"/>
            </jxb:bindings>
            <jxb:bindings node="//xs:simpleType[@name='educationLevelType']/xs:restriction/xs:enumeration[@value='11']">
                <jxb:typesafeEnumMember name="ELEVEN"/>
            </jxb:bindings>
            <jxb:bindings node="//xs:simpleType[@name='educationLevelType']/xs:restriction/xs:enumeration[@value='12']">
                <jxb:typesafeEnumMember name="TWELVE"/>
            </jxb:bindings>
            <jxb:bindings node="//xs:simpleType[@name='educationLevelType']/xs:restriction/xs:enumeration[@value='']">
                <jxb:typesafeEnumMember name="BLANK"/>
            </jxb:bindings>
        </jxb:bindings>
    </jxb:bindings>
    

    The XJC call can be made as follows (the -nv flag is described below):

    xjc -nv -b bindings.xml -d out http://www.acf.hhs.gov/programs/cb/systems/nytd/nytd_data_file_format.xsd
    

    This will cause the following Enum to be generated:

    package gov.hhs.acf.nytd;
    
    import javax.xml.bind.annotation.XmlEnum;
    import javax.xml.bind.annotation.XmlEnumValue;
    import javax.xml.bind.annotation.XmlType;
    
    @XmlType(name = "educationLevelType")
    @XmlEnum
    public enum EducationLevelType {
    
        @XmlEnumValue("under 6")
        UNDER_6("under 6"),
    
        @XmlEnumValue("6")
        SIX("6"),
    
        @XmlEnumValue("7")
        SEVEN("7"),
    
        @XmlEnumValue("8")
        EIGHT("8"),
    
        @XmlEnumValue("9")
        NINE("9"),
    
        @XmlEnumValue("10")
        TEN("10"),
    
        @XmlEnumValue("11")
        ELEVEN("11"),
    
        @XmlEnumValue("12")
        TWELVE("12"),
    
        @XmlEnumValue("post secondary")
        POST_SECONDARY("post secondary"),
    
        @XmlEnumValue("college")
        COLLEGE("college"),
        @XmlEnumValue("")
    
        BLANK("");
        private final String value;
    
        EducationLevelType(String v) {
            value = v;
        }
    
        public String value() {
            return value;
        }
    
        public static EducationLevelType fromValue(String v) {
            for (EducationLevelType c: EducationLevelType.values()) {
                if (c.value.equals(v)) {
                    return c;
                }
            }
            throw new IllegalArgumentException(v);
        }
    
    }
    

    maxOccurs Issue

    For the maxOccurs issue, the following command line with the no verify (-nv) flag can be used to parse the XML schema:

    xjc -nv -d out http://www.acf.hhs.gov/programs/cb/systems/nytd/nytd_data_file_format.xsd
    

    This will get you past the following error without having to modify the XML schema:

    parsing a schema... [ERROR] Current configuration of the parser doesn't allow a maxOccurs attribute value to be set greater than the value 5,000.
    line 41 of http://www.acf.hhs.gov/programs/cb/systems/nytd/nytd_data_file_format.xsd

    Failed to parse a schema.

    For More Information

    • http://blog.bdoughan.com/2011/08/jaxb-and-enums.html
    0 讨论(0)
  • 2020-12-14 09:30

    Yes. You could define the enum yourself instead of having XJC generate it. Then you could instruct XJC to use that enum. You'll need an adapter class, though.

    import acme.MyEnum;
    
    public class MyEnumadapter {
    
        public static MyEnum unmarshal(final String value) {
            if(value == null)
                return null;
            //use some method to identify the enum by the value and return
        }
    
        public static String marshal(final MyEnum value) {
            if (value == null)
                return null;
            //use some method to get the value for the enum
        }
    
    }
    

    Either in a bindings file or embedded in the schema, customize the bindings like this:

    <bindings node="//xs:simpleType[@name='SomeCode']">
        <javaType name="acme.MyEnum"
            parseMethod="MyEnumAdapter.unmarshal"
            printMethod="MyEnumAdapter.marshal"/>
    </bindings>
    

    MyEnumAdapter is in the default package here, so make sure you use the fully qualified names when doing this yourself.

    0 讨论(0)
提交回复
热议问题