枚举与架构:jaxb或xsd的问题不匹配?

end*_*ser 5 enums jaxb unmarshalling

我正在尝试使用JAXB 将此文件解组为Java对象.我知道J6中的SAX存在一个问题,即拒绝maxOccurs线,我已将其更改为unbounded.但是,当我xjc这样做时,它并没有创建我需要的所有类和枚举.例如,应该有一个educationLevelType枚举.更重要的是,我尝试了MS的xsd unmarshaller,它正确地创造了一切.

有经验的人比我看这个并且告诉我我缺少的东西吗?是否需要在xsd中更正某些内容,或者JAXB中是否存在错误?

根据要求,更新 Blaise完全回答了这个问题.不幸的是,恕我直言,这使得JAXB毫无价值.整个想法是我可以从模式生成类 - 我不应该事先知道结构的东西.如果我必须创建一个自定义绑定文件,我不妨创建一个生成我想要的代码的模式.但那么,为什么要停在那里?为什么不跳过所有这些步骤并生成我想要的类?

最后,一位同事向我指出了Apache XMLBeans--该项目有点旧,但它创建的对象没有任何问题.Codehaus还有一个xmlbeans-maven-plugin.

bdo*_*han 7

有几个枚举值导致此问题.通过使用JAXB外部绑定文件可以克服这些问题(见下文).

枚举问题#1 - 空字符串

你的一些枚举值是空字符串(""),它导致生成一个String而不是一个枚举属性:

<xs:enumeration value="">
    <xs:annotation>
        <xs:documentation>Blank</xs:documentation> 
    </xs:annotation>
</xs:enumeration>
Run Code Online (Sandbox Code Playgroud)

枚举问题#2 - 数字字符串

某些枚举值是导致生成String而不是枚举属性的数字:

<xs:enumeration value="6">
    <xs:annotation>
        <xs:documentation>6th grade</xs:documentation> 
   </xs:annotation>
</xs:enumeration>
Run Code Online (Sandbox Code Playgroud)

绑定文件(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>
Run Code Online (Sandbox Code Playgroud)

XJC调用可以如下进行(-nv标志如下所述):

xjc -nv -b bindings.xml -d out http://www.acf.hhs.gov/programs/cb/systems/nytd/nytd_data_file_format.xsd
Run Code Online (Sandbox Code Playgroud)

这将导致生成以下枚举:

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);
    }

}
Run Code Online (Sandbox Code Playgroud)

maxOccurs问题

对于maxOccurs问题,可以使用以下带有no verify(-nv)标志的命令行来解析XML模式:

xjc -nv -d out http://www.acf.hhs.gov/programs/cb/systems/nytd/nytd_data_file_format.xsd
Run Code Online (Sandbox Code Playgroud)

这将使您无需修改​​XML架构即可通过以下错误:

解析模式... [错误]解析器的当前配置不允许将maxOccurs属性值设置为大于值5,000.http://www.acf.hhs.gov/programs/cb/systems/nytd/nytd_data_file_format.xsd
第41行

无法解析架构.

欲获得更多信息


小智 5

您也可以使用具有typesafeEnumMemberName ="generateName"的globalBindings,而不是为每个枚举值指定绑定.

<?xml version="1.0" encoding="UTF-8"?>
<bindings xmlns="http://java.sun.com/xml/ns/jaxb"
                xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
                xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
                xsi:schemaLocation="
http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"
    version="2.1" schemaLocation="xxxxxxxxx.xsd" >
    <schemaBindings>
        <package name="xx.xx.xx" />
    </schemaBindings>
    <globalBindings typesafeEnumMemberName="generateName"/>
</bindings>
Run Code Online (Sandbox Code Playgroud)

http://download.oracle.com/docs/cd/E17802_01/webservices/webservices/docs/1.5/tutorial/doc/JAXBUsing4.html#wp148515