线程 "main" "javax.xml.bind.UnmarshalException: unexpected element" 中的异常但是需要同时允许 test-classes 和 test-class

Exception in thread "main" "javax.xml.bind.UnmarshalException: unexpected element" BUT it is required to allow both test-classes and test-class

我在 运行 以下代码时遇到异常:

JAXBContext context = JAXBContext.newInstance(TestClassesType.class , TestClassType.class);
Unmarshaller um = context.createUnmarshaller();
System.out.println("XMLFILE ==  " + xmlFilePath);
JAXBElement tcstJaxb = (JAXBElement) um.unmarshal(new FileReader(xmlFilePath));

异常:

Exception in thread "main" javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"test-class"). Expected elements are <{}test-classes>
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:647)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:243)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:238)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:105)

我在代码段中指定了 TestClassesType.class 和 TestClassType.class : JAXBContext context = JAXBContext.newInstance(TestClassesType.class , TestClassType.class); 但是当某些 xml 以 test-classes 开头时,它仍然是能够解组但 classes 以 test-class 开头,它无法解组并抛出上述异常。 类 使用过: 测试类类型

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "test-classesType", propOrder = {
    "testClass"
})
public class TestClassesType {

    @XmlElement(name = "test-class")
    protected List<TestClassType> testClass;

    /**
     * Gets the value of the testClass property.
     * 
     * <p>
     * This accessor method returns a reference to the live list,
     * not a snapshot. Therefore any modification you make to the
     * returned list will be present inside the JAXB object.
     * This is why there is not a <CODE>set</CODE> method for the testClass property.
     * 
     * <p>
     * For example, to add a new item, do as follows:
     * <pre>
     *    getTestClass().add(newItem);
     * </pre>
     * 
     * 
     * <p>
     * Objects of the following type(s) are allowed in the list
     * {@link TestClassType }
     * 
     * 
     */
    public List<TestClassType> getTestClass() {
        if (testClass == null) {
            testClass = new ArrayList<TestClassType>();
        }
        return this.testClass;
    }

}

测试类类型:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "test-classType", propOrder = {
    "content"
})
public class TestClassType {

    @XmlElementRef(name = "test-method", type = JAXBElement.class, required = false)
    @XmlMixed
    protected List<Serializable> content;
    @XmlAttribute(name = "name")
    protected String name;

    /**
     * Gets the value of the content property.
     * 
     * <p>
     * This accessor method returns a reference to the live list,
     * not a snapshot. Therefore any modification you make to the
     * returned list will be present inside the JAXB object.
     * This is why there is not a <CODE>set</CODE> method for the content property.
     * 
     * <p>
     * For example, to add a new item, do as follows:
     * <pre>
     *    getContent().add(newItem);
     * </pre>
     * 
     * 
     * <p>
     * Objects of the following type(s) are allowed in the list
     * {@link String }
     * {@link JAXBElement }{@code <}{@link TestMethodType }{@code >}
     * 
     * 
     */
    public List<Serializable> getContent() {
        if (content == null) {
            content = new ArrayList<Serializable>();
        }
        return this.content;
    }

    /**
     * Gets the value of the name property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getName() {
        return name;
    }

    /**
     * Sets the value of the name property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setName(String value) {
        this.name = value;
    }

}

我有几个以 test-class 开头的 xml 和一些以 test-class 标签开头的。我想允许这两个。有什么办法可以做到这一点吗?

如此生成的 ObjectFactory class 如下所示:

@XmlRegistry
public class ObjectFactory {

    private final static QName _TestClasses_QNAME = new QName("", "test-classes");
    private final static QName _TestClassTypeTestMethod_QNAME = new QName("", "test-method");

    /**
     * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: com.jaxb.scenario
     * 
     */
    public ObjectFactory() {
    }

    /**
     * Create an instance of {@link TestClassesType }
     * 
     */
    public TestClassesType createTestClassesType() {
        return new TestClassesType();
    }

    /**
     * Create an instance of {@link ParamsType }
     * 
     */
    public ParamsType createParamsType() {
        return new ParamsType();
    }

    /**
     * Create an instance of {@link TestCaseType }
     * 
     */
    public TestCaseType createTestCaseType() {
        return new TestCaseType();
    }

    /**
     * Create an instance of {@link TestClassType }
     * 
     */
    public TestClassType createTestClassType() {
        return new TestClassType();
    }

    /**
     * Create an instance of {@link AssertType }
     * 
     */
    public AssertType createAssertType() {
        return new AssertType();
    }

    /**
     * Create an instance of {@link TestMethodType }
     * 
     */
    public TestMethodType createTestMethodType() {
        return new TestMethodType();
    }

    /**
     * Create an instance of {@link AssertsType }
     * 
     */
    public AssertsType createAssertsType() {
        return new AssertsType();
    }

    /**
     * Create an instance of {@link ParamType }
     * 
     */
    public ParamType createParamType() {
        return new ParamType();
    }

    /**
     * Create an instance of {@link JAXBElement }{@code <}{@link TestClassesType }{@code >}}
     * 
     */
    @XmlElementDecl(namespace = "", name = "test-classes")
    public JAXBElement<TestClassesType> createTestClasses(TestClassesType value) {
        return new JAXBElement<TestClassesType>(_TestClasses_QNAME, TestClassesType.class, null, value);
    }

    /**
     * Create an instance of {@link JAXBElement }{@code <}{@link TestMethodType }{@code >}}
     * 
     */
    @XmlElementDecl(namespace = "", name = "test-method", scope = TestClassType.class)
    public JAXBElement<TestMethodType> createTestClassTypeTestMethod(TestMethodType value) {
        return new JAXBElement<TestMethodType>(_TestClassTypeTestMethod_QNAME, TestMethodType.class, TestClassType.class, value);
    }

}

test-class 元素是否对应于 ObjectFactory class 上的 @XmlElementDecl 注释(或者您用 [=14= 注释的 class ]? 如果是这样,您需要在 bootstrap 您的 JAXBContext.

时包含它
JAXBContext context = JAXBContext.newInstance(ObjectFactory.class);

如果您从 XML 架构生成模型,则 ObjectFactory class 是您唯一需要传递给 bootstrap 和 JAXBContext.