このように入力値を制限したい
<simpleType name="SomeCode">
<restriction base="string">
<enumeration value="036222B"/>
<enumeration value="036111C"/>
</restriction>
</simpleType>
ただし、これは列挙型を生成しません。値が数字で始まり、これが列挙値では許可されていないためだと思います。
解決策や回避策はありますか?
これが役立つかもしれない同様の質問に対する私の答えです(問題2を参照):
この問題の原因となっている列挙値がいくつかあります。これらの問題は、JAXB外部バインディングファイルを使用することで克服できます(以下を参照)。
列挙型問題#1-空の文字列
一部の列挙値は空の文字列( "")であるため、列挙プロパティではなく文字列が生成されます。
<xs:enumeration value="">
<xs:annotation>
<xs:documentation>Blank</xs:documentation>
</xs:annotation>
</xs:enumeration>
列挙型問題#2-数値文字列
列挙値の一部は数値であり、列挙プロパティではなく文字列が生成されます。
<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
これにより、次の列挙型が生成されます。
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属性値を値5,000より大きく設定することはできません。
41行目 http://www.acf.hhs.gov/programs/cb/systems/nytd/nytd_data_file_format.xsdスキーマの解析に失敗しました。
詳細情報
はい。 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はここのデフォルトパッケージに含まれているため、これを自分で行う場合は、完全修飾名を使用するようにしてください。
このコードはもっと簡単な方法で、私にとってはうまくいきます。
@XmlEnum(value = Integer.class)
public enum SomeEnum {
@XmlEnumValue("0")
Value1,
@XmlEnumValue("1")
Value2,
@XmlEnumValue("2")
Value3;
}