Перечисление JAXB с числовыми значениями - PullRequest
19 голосов
/ 24 августа 2011

Я хочу ограничить входные значения, как это

<simpleType name="SomeCode">
  <restriction base="string">
    <enumeration value="036222B"/>
    <enumeration value="036111C"/>
  </restriction>
</simpleType>

Но это не генерирует Enum. Я подозреваю, что это потому, что значения начинаются с цифр, и это не допускается для значений Enum.

Есть ли решение или обходной путь?

Ответы [ 3 ]

45 голосов
/ 24 августа 2011

Вот мой ответ на похожий вопрос, который может помочь (см. Выпуск 2):

Существует несколько значений перечисления, которые вызывают эту проблему.Эти проблемы могут быть преодолены с помощью внешнего файла привязки JAXB (см. Ниже).

Enum Issue # 1 - Empty String

Некоторые из значений enum являются пустой строкой (""), которая вызывает свойство String, а не свойство enumсгенерировано:

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

Перечисление Выпуск # 2 - Числовая строка

Некоторые из значений перечисления являются числами, что вызывает создание свойства String, а не свойства enum:

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

Файл привязок (bindings.xml)

Следующий файл привязок можно использовать для решения проблем с educationLevelType ,Приведенные здесь понятия могут быть применены ко всем проблемным типам:

<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>

Вызов XJC может быть выполнен следующим образом (флаг -nv описан ниже):

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

Это будетвызвать генерирование следующего Enum:

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

Для проблемы maxOccurs, следующая командная строка с no verify (-nv) флаг может быть использован для анализа схемы XML:

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

Это поможет вамСледующая ошибка без изменения схемы XML:

синтаксический анализ схемы ... [ОШИБКА] Текущая конфигурация синтаксического анализатора не позволяет установить значение атрибута maxOccurs больше, чем значение 5000.
строка 41 из http://www.acf.hhs.gov/programs/cb/systems/nytd/nytd_data_file_format.xsd

Не удалось проанализировать схему.

Для получения дополнительной информации

5 голосов
/ 24 августа 2011

Да.Вы можете сами определить перечисление вместо того, чтобы XJC его генерировал.Тогда вы могли бы поручить XJC использовать это перечисление.Однако вам понадобится класс адаптера.

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
    }

}

Либо в файле привязок, либо встроенном в схему, настройте привязки следующим образом:

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

MyEnumAdapter используется по умолчаниюпакет здесь, поэтому убедитесь, что вы используете полные имена, когда делаете это самостоятельно.

2 голосов
/ 30 апреля 2018

Этот код более простой способ, у меня работает.

@XmlEnum(value = Integer.class)
public enum SomeEnum {
  @XmlEnumValue("0")
  Value1,
  @XmlEnumValue("1")
  Value2,
  @XmlEnumValue("2")
  Value3;
}
...