Перечисления не соответствуют схеме: проблема с jaxb или xsd? - PullRequest
5 голосов
/ 27 января 2011

Я пытаюсь использовать JAXB для демаршалирования этого файла в объекты Java.Я знаю, что есть проблема с SAX в J6, которая отклоняет строку maxOccurs, и я изменил ее на unbounded.Однако, когда я xjc это, это не создает все классы и перечисления, в которых я нуждаюсь.Например, должно быть перечисление educationLevelType.Более того, я попробовал xsd unmarshaller от MS, он все создает правильно.

Может ли кто-нибудь с большим опытом, чем я, посмотреть на это и сказать мне, что мне не хватает?Есть ли что-то, что должно быть исправлено в xsd, или есть ошибка в JAXB?

Обновление Блейз полностью ответил на этот вопрос в ответ на вопрос.К сожалению, ИМХО, это делает JAXB бесполезным.Идея заключается в том, что я могу генерировать классы из схемы - мне не нужно знать заранее о структуре.Если мне нужно создать пользовательский файл привязок, я мог бы просто создать схему, которая производит код, который я хочу.Но тогда зачем останавливаться на достигнутом?Почему бы просто не пропустить все эти шаги и сгенерировать нужные мне классы?

В конце коллега указал мне на Apache XMLBeans - проект немного старше, но он создает объекты безбеда.Codehaus также имеет для этого xmlbeans-maven-plugin .

Ответы [ 3 ]

7 голосов
/ 28 января 2011

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

Enum Issue # 1 - Пустая строка

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

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

Enum Issue # 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

Это приведет к созданию следующего 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 для анализа схемы XML можно использовать следующую командную строку с флагом no verify (-nv):

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 голосов
/ 21 июня 2011

Вместо указания привязки для каждого значения перечисления вы также можете использовать globalBindings с typesafeEnumMemberName = "generateName"

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

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

0 голосов
/ 01 февраля 2011

XMLBeans также не генерирует перечисление для этой схемы XML. При использовании XMLBeans 2.5.0 (последний из http://xmlbeans.apache.org/), генерируется следующее для образованияLevelType:

<code>/*
 * XML Type:  educationLevelType
 * Namespace: http://nytd.acf.hhs.gov
 * Java type: gov.hhs.acf.nytd.EducationLevelType
 *
 * Automatically generated - do not modify.
 */
package gov.hhs.acf.nytd;


/**
 * An XML educationLevelType(@http://nytd.acf.hhs.gov).
 *
 * This is an atomic type that is a restriction of gov.hhs.acf.nytd.EducationLevelType.
 */
public interface EducationLevelType extends org.apache.xmlbeans.XmlString
{
    public static final org.apache.xmlbeans.SchemaType type = (org.apache.xmlbeans.SchemaType)
        org.apache.xmlbeans.XmlBeans.typeSystemForClassLoader(EducationLevelType.class.getClassLoader(), "schemaorg_apache_xmlbeans.system.s1A8CC5216945B0856A28CEF895800DEB").resolveHandle("educationleveltypeb147type");

    org.apache.xmlbeans.StringEnumAbstractBase enumValue();
    void set(org.apache.xmlbeans.StringEnumAbstractBase e);

    static final Enum UNDER_6 = Enum.forString("under 6");
    static final Enum X_6 = Enum.forString("6");
    static final Enum X_7 = Enum.forString("7");
    static final Enum X_8 = Enum.forString("8");
    static final Enum X_9 = Enum.forString("9");
    static final Enum X_10 = Enum.forString("10");
    static final Enum X_11 = Enum.forString("11");
    static final Enum X_12 = Enum.forString("12");
    static final Enum POST_SECONDARY = Enum.forString("post secondary");
    static final Enum COLLEGE = Enum.forString("college");
    static final Enum X = Enum.forString("");

    static final int INT_UNDER_6 = Enum.INT_UNDER_6;
    static final int INT_X_6 = Enum.INT_X_6;
    static final int INT_X_7 = Enum.INT_X_7;
    static final int INT_X_8 = Enum.INT_X_8;
    static final int INT_X_9 = Enum.INT_X_9;
    static final int INT_X_10 = Enum.INT_X_10;
    static final int INT_X_11 = Enum.INT_X_11;
    static final int INT_X_12 = Enum.INT_X_12;
    static final int INT_POST_SECONDARY = Enum.INT_POST_SECONDARY;
    static final int INT_COLLEGE = Enum.INT_COLLEGE;
    static final int INT_X = Enum.INT_X;

    /**
     * Enumeration value class for gov.hhs.acf.nytd.EducationLevelType.
     * These enum values can be used as follows:
     * <pre>
     * enum.toString(); // returns the string value of the enum
     * enum.intValue(); // returns an int value, useful for switches
     * // e.g., case Enum.INT_UNDER_6
     * Enum.forString(s); // returns the enum value for a string
     * Enum.forInt(i); // returns the enum value for an int
     * 
* Объекты перечисления являются неизменяемыми одноэлементными объектами, которые * можно сравнить, используя == равенство объектов. У них нет * общественный конструктор. Смотрите константы, определенные в этом * класс для всех допустимых значений. * / статический конечный класс Enum extends org.apache.xmlbeans.StringEnumAbstractBase { / ** * Возвращает значение перечисления для строки или ноль, если его нет. * / открытый статический Enum forString (java.lang.String s) {return (Enum) table.forString (s); } / ** * Возвращает значение enum, соответствующее int, или null, если его нет. * / открытый статический Enum forInt (int i) {return (Enum) table.forInt (i); } частное перечисление (java.lang.String s, int i) {супер (с, я); } static final int INT_UNDER_6 = 1; static final int INT_X_6 = 2; static final int INT_X_7 = 3; static final int INT_X_8 = 4; static final int INT_X_9 = 5; static final int INT_X_10 = 6; static final int INT_X_11 = 7; static final int INT_X_12 = 8; static final int INT_POST_SECONDARY = 9; static final int INT_COLLEGE = 10; static final int INT_X = 11; public static final org.apache.xmlbeans.StringEnumAbstractBase.Table table = new org.apache.xmlbeans.StringEnumAbstractBase.Table ( новый Enum [] { новый Enum ("до 6 лет", INT_UNDER_6), новый Enum ("6", INT_X_6), новый Enum ("7", INT_X_7), новый Enum ("8", INT_X_8), новый Enum ("9", INT_X_9), новый Enum ("10", INT_X_10), новый Enum ("11", INT_X_11), новый Enum ("12", INT_X_12), новый Enum («вторичный пост», INT_POST_SECONDARY), новый Enum ("колледж", INT_COLLEGE), новый Enum ("", INT_X), } ); приватный статический финал long serialVersionUID = 1L; private java.lang.Object readResolve () {return forInt (intValue ()); } } / ** * Фабричный класс со статическими методами для создания экземпляров * этого типа. * / общедоступный статический финальный класс Factory { public static gov.hhs.acf.nytd.EducationLevelType newValue (java.lang.Object obj) { return (gov.hhs.acf.nytd.EducationLevelType) type.newValue (obj); } public static gov.hhs.acf.nytd.EducationLevelType newInstance () { return (gov.hhs.acf.nytd.EducationLevelType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader (). newInstance (тип, ноль); } общедоступный статический gov.hhs.acf.nytd.EducationLevelType newInstance (параметры org.apache.xmlbeans.XmlOptions) { return (gov.hhs.acf.nytd.EducationLevelType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader (). newInstance (тип, параметры); } / ** @param xmlAsString строковое значение для разбора * / public static gov.hhs.acf.nytd.EducationLevelType parse (java.lang.String xmlAsString) выбрасывает org.apache.xmlbeans.XmlException { return (gov.hhs.acf.nytd.EducationLevelType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader (). parse (xmlAsString, type, null); } открытый статический gov.hhs.acf.nytd.EducationLevelType parse (параметры java.lang.String xmlAsString, org.apache.xmlbeans.XmlOptions) создает org.apache.xmlbeans.XmlException { return (gov.hhs.acf.nytd.EducationLevelType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader (). parse (xmlAsString, тип, параметры); } / ** @param file файл, из которого загружается XML-документ * / открытый статический gov.hhs.acf.nytd.EducationLevelType parse (файл java.io.File) генерирует org.apache.xmlbeans.XmlException, java.io.IOException {return (gov.hhs.acf.nytd.EducationLevelType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader (). parse (file, type, null); } открытый статический gov.hhs.acf.nytd.EducationLevelType parse (файл java.io.File, параметры org.apache.xmlbeans.XmlOptions) выдает org.apache.xmlbeans.XmlException, java.io.IOException { return (gov.hhs.acf.nytd.EducationLevelType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader (). parse (файл, тип, параметры); } public static gov.hhs.acf.nytd.EducationLevelType parse (java.net.URL u) выбрасывает org.apache.xmlbeans.XmlException, java.io.IOException { return (gov.hhs.acf.nytd.EducationLevelType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader (). parse (u, type, null); } public static gov.hhs.acf.nytd.EducationLevelType parse (параметры java.net.URL u, org.apache.xmlbeans.XmlOptions) выдает org.apache.xmlbeans.XmlException, java.io.IOException { return (gov.hhs.acf.nytd.EducationLevelType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader (). parse (u, type, options); } public static gov.hhs.acf.nytd.EducationLevelType parse (java.io.InputStream is) выдает org.apache.xmlbeans.XmlException, java.io.IOException { return (gov.hhs.acf.nytd.EducationLevelType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader (). parse (is, type, null); } public static gov.hhs.acf.nytd.EducationLevelType parse (параметры java.io.InputStream, org.apache.xmlbeans.XmlOptions) генерирует org.apache.xmlbeans.XmlException, java.io.IOException { return (gov.hhs.acf.nytd.EducationLevelType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader (). parse (есть, тип, параметры); } public static gov.hhs.acf.nytd.EducationLevelType parse (java.io.Reader r) выбрасывает org.apache.xmlbeans.XmlException, java.io.IOException { return (gov.hhs.acf.nytd.EducationLevelType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader (). parse (r, type, null); } public static gov.hhs.acf.nytd.EducationLevelType parse (параметры java.io.Reader r, org.apache.xmlbeans.XmlOptions) выдает org.apache.xmlbeans.XmlException, java.io.IOException { return (gov.hhs.acf.nytd.EducationLevelType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader (). parse (r, тип, параметры); } public static gov.hhs.acf.nytd.EducationLevelType parse (javax.xml.stream.XMLStreamReader sr) выбрасывает org.apache.xmlbeans.XmlException { return (gov.hhs.acf.nytd.EducationLevelType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader (). parse (sr, type, null); } общедоступный статический gov.hhs.acf.nytd.EducationLevelType parse (параметры javax.xml.stream.XMLStreamReader sr, org.apache.xmlbeans.XmlOptions) создает org.apache.xmlbeans.XmlException { return (gov.hhs.acf.nytd.EducationLevelType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader (). parse (sr, type, options); } общедоступный статический анализ gov.hhs.acf.nytd.EducationLevelType (узел org.w3c.dom.Node) создает org.apache.xmlbeans.XmlException { return (gov.hhs.acf.nytd.EducationLevelType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader (). parse (узел, тип, ноль); } открытый статический gov.hhs.acf.nytd.EducationLevelType parse (узел org.w3c.dom.Node, параметры org.apache.xmlbeans.XmlOptions) генерирует org.apache.xmlbeans.XmlException { return (gov.hhs.acf.nytd.EducationLevelType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader (). parse (узел, тип, параметры); } / ** @deprecated {@link org.apache.xmlbeans.xml.stream.XMLInputStream} * / public static gov.hhs.acf.nytd.EducationLevelType parse (org.apache.xmlbeans.xml.stream.XMLInputStream xis) создает org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xml.stream.XMLStreamException { return (gov.hhs.acf.nytd.EducationLevelType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader (). parse (xis, type, null); } / ** @deprecated {@link org.apache.xmlbeans.xml.stream.XMLInputStream} * /public static gov.hhs.acf.nytd.EducationLevelType parse (параметры org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions) выдает org.apache.xmlbeans.XmlException или org.apache.xmlbeans. xml.stream.XMLStreamException { return (gov.hhs.acf.nytd.EducationLevelType) org.apache.xmlbeans.XmlBeans.getContextTypeLoader (). parse (xis, type, options); } / ** @deprecated {@link org.apache.xmlbeans.xml.stream.XMLInputStream} * / общедоступная статическая org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream (org.apache.xmlbeans.xml.stream.XMLInputStream xis) создает org.apache.xmlbeans.XmlException, org.apache.xmlbeans.xream.stream.X return org.apache.xmlbeans.XmlBeans.getContextTypeLoader (). newValidatingXMLInputStream (xis, type, null); } / ** @deprecated {@link org.apache.xmlbeans.xml.stream.XMLInputStream} * / общедоступные статические org.apache.xmlbeans.xml.stream.XMLInputStream newValidatingXMLInputStream (параметры org.apache.xmlbeans.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions) org.apache.xmlbeans.XgacheException или. xmlbeans.xml.stream.XMLStreamException { return org.apache.xmlbeans.XmlBeans.getContextTypeLoader (). newValidatingXMLInputStream (xis, type, options); } private Factory () {} // Экземпляр этого класса запрещен } }
...