JAXB Unmarshall 错误:UnmarshalException- 意外元素 - 预期元素为(无) - @XmlRootElement 不缺失

mbm*_*ast 5 java xml xsd jaxb xjc

我在解组某些 XML 时遇到问题。部分堆栈转储如下所示:

javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"properties"). Expected elements are (none)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:726)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:247)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:242)
Run Code Online (Sandbox Code Playgroud)

下面是我尝试解组的 XML、XJC 生成的根元素 Java 类、输入 XJC 的 XSD 以及最后 XJC 生成的 ObjectFactory。

我正在解组的 XML:

<?xml version="1.0" encoding="UTF-8"?>
<properties program-name="EstateAccounting"
                        properties-file="EstateAccounting.properties">
                        
    <keyword-properties>
        <keyword-property type="string" name="reportDirectory" alias="rd">
            <description>
                <![CDATA[Specifies the optional report directory.  Double quotes are required if the report directory
                contains spaces.  The report directory specifies where the intermediate XML used to produce the PDF report
                and where the PDF report should be produced.]]>
            </description>
        </keyword-property>
        
        <keyword-property type="string" name="beneficiary" alias="b">
            <description>
                <![CDATA[Specifies the optional beneficary name.  Double quotes are required if the beneficiary name
                contains spaces.  When omitted, all beneficiaries are included.]]>
            </description>
        </keyword-property>
        
        <keyword-property type="string" name="date" alias="d">
            <description>
                <![CDATA[Specifies the optional date(s).  The format is mm/yyyy.  Double quotes are required 
                when specifying a date range as "start-date - end-date" (spaces optional).  When omitted,
                all dates are included.]]>
            </description>
        </keyword-property>
        
        <keyword-property type="boolean" name="isGenerateReport" alias="r">
            <description>
                <![CDATA[Indicates that a PDF report should be produced.  One report for each generated XML file will be produced.]]>
            </description>
        </keyword-property>
        
        <keyword-property type="boolean" name="isKeepIntermediateXML" alias="xml">
            <description>
                <![CDATA[Indicates that the XML file used to produce the PDF report should be retained.  Normally, when the -r option
                indicates that a PDF report should be produced, the generated intermediate XML file is deleted.]]>
            </description>
        </keyword-property>
    </keyword-properties>
    
    <positional-properties>
        <positional-property type="string" name="spreadsheet" required="false">
            <description>
                <![CDATA[The location of the input spreadsheet.]]>
            </description>
        </positional-property>
        
        <positional-property type="string" name="intermediateXML" required="false">
            <description>
                <![CDATA[The location of a previously generated EstateAccounting intermediate XML file.  This is specified when 
                 a report based on previously generated intermediate XML is required.]]>
            </description>
        </positional-property>
    </positional-properties>
    
    <mutual-properties>
        <mutual-property-set type="exclusive">
            <mutual-property name="spreadsheet"/>
            <mutual-property name="intermediateXML"/>
        </mutual-property-set>
    </mutual-properties>
</properties>
Run Code Online (Sandbox Code Playgroud)

部分XJC生成根元素Java类。@XmlRootElement(name = "properties")请注意类中包含Properties

//
// This file was generated by the Eclipse Implementation of JAXB, v3.0.2 
// See https://eclipse-ee4j.github.io/jaxb-ri 
// Any modifications to this file will be lost upon recompilation of the source schema. 
// Generated on: 2022.01.26 at 10:38:30 AM PST 
//

package com.mbm.properties.jaxb;

import java.util.ArrayList;
import java.util.List;
import jakarta.xml.bind.annotation.XmlAccessType;
import jakarta.xml.bind.annotation.XmlAccessorType;
import jakarta.xml.bind.annotation.XmlAttribute;
import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlRootElement;
import jakarta.xml.bind.annotation.XmlTransient;
import jakarta.xml.bind.annotation.XmlType;
import org.glassfish.jaxb.core.Locatable;
import org.glassfish.jaxb.core.annotation.XmlLocation;
import org.xml.sax.Locator;


/**
 * <p>Java class for anonymous complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType&gt;
 *   &lt;complexContent&gt;
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"&gt;
 *       &lt;sequence&gt;
 *         &lt;element name="description" type="{urn:com-mbm-properties-jaxb}descriptionType" maxOccurs="unbounded" minOccurs="0"/&gt;
 *         &lt;element name="keyword-properties" type="{urn:com-mbm-properties-jaxb}keywordPropertiesType" minOccurs="0"/&gt;
 *         &lt;element name="positional-properties" type="{urn:com-mbm-properties-jaxb}positionalPropertiesType" minOccurs="0"/&gt;
 *         &lt;element name="mutual-properties" type="{urn:com-mbm-properties-jaxb}MutualPropertiesType" minOccurs="0"/&gt;
 *       &lt;/sequence&gt;
 *       &lt;attribute name="program-name" type="{http://www.w3.org/2001/XMLSchema}string" /&gt;
 *       &lt;attribute name="properties-file" type="{http://www.w3.org/2001/XMLSchema}string" /&gt;
 *       &lt;attribute name="debug" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" /&gt;
 *       &lt;attribute name="strict-property-retrieval" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" /&gt;
 *       &lt;attribute name="strict-command-line" type="{http://www.w3.org/2001/XMLSchema}boolean" default="true" /&gt;
 *       &lt;attribute name="usage" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" /&gt;
 *     &lt;/restriction&gt;
 *   &lt;/complexContent&gt;
 * &lt;/complexType&gt;
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "descriptions",
    "containerOfListOfKeywordProperties",
    "containerOfListOfPositionalProperties",
    "mutualProperties"
})
@XmlRootElement(name = "properties")
public class Properties
    implements Locatable
{

    @XmlElement(name = "description")
    protected List<DescriptionType> descriptions;
    @XmlElement(name = "keyword-properties")
    protected KeywordPropertiesType containerOfListOfKeywordProperties;
    @XmlElement(name = "positional-properties")
    protected PositionalPropertiesType containerOfListOfPositionalProperties;
    @XmlElement(name = "mutual-properties")
    protected MutualPropertiesType mutualProperties;
    @XmlAttribute(name = "program-name")
    protected String programName;
    @XmlAttribute(name = "properties-file")
    protected String propertiesFile;
    @XmlAttribute(name = "debug")
    protected Boolean debug;
    @XmlAttribute(name = "strict-property-retrieval")
    protected Boolean strictPropertyRetrieval;
    @XmlAttribute(name = "strict-command-line")
    protected Boolean strictCommandLine;
    @XmlAttribute(name = "usage")
    protected Boolean usage;
    @XmlLocation
    @XmlTransient
    protected Locator locator;

    .
    .
    .

    public Locator sourceLocation() {
        return locator;
    }

    public void setSourceLocation(Locator newLocator) {
        locator = newLocator;
    }
}
Run Code Online (Sandbox Code Playgroud)

XSD 馈入生成 Java 类的 XJC:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
            xmlns:jaxb="https://jakarta.ee/xml/ns/jaxb"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns="urn:com-mbm-properties-jaxb"
            targetNamespace="urn:com-mbm-properties-jaxb"
            elementFormDefault="qualified"
            jaxb:extensionBindingPrefixes="xjc"
            jaxb:version="3.0">

    <xsd:annotation>
        <xsd:appinfo>
            <jaxb:globalBindings>
                <xjc:simple/>
            </jaxb:globalBindings>
        </xsd:appinfo>
    </xsd:annotation>
    
    <xsd:element name="properties">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="description" type="descriptionType" minOccurs="0" maxOccurs="unbounded"/>
                <xsd:element name="keyword-properties" type="keywordPropertiesType" minOccurs="0" maxOccurs="1">
                    <xsd:annotation>
                        <xsd:appinfo>
                            <jaxb:property name="containerOfListOfKeywordProperties"/>
                        </xsd:appinfo>
                    </xsd:annotation>
                </xsd:element>
                <xsd:element name="positional-properties" type="positionalPropertiesType" minOccurs="0" maxOccurs="1">
                    <xsd:annotation>
                        <xsd:appinfo>
                            <jaxb:property name="containerOfListOfPositionalProperties"/>
                        </xsd:appinfo>
                    </xsd:annotation>
                </xsd:element>
                <xsd:element name="mutual-properties" type="MutualPropertiesType" minOccurs="0" maxOccurs="1"/>
            </xsd:sequence>
            <xsd:attribute name="program-name" type="xsd:string" use="optional"/>
            <xsd:attribute name="properties-file" type="xsd:string" use="optional"/>
            <xsd:attribute name="debug" type="xsd:boolean" use="optional" default="false"/>
            <xsd:attribute name="strict-property-retrieval" type="xsd:boolean" use="optional" default="true"/>
            <xsd:attribute name="strict-command-line" type="xsd:boolean" use="optional" default="true"/>
            <xsd:attribute name="usage" type="xsd:boolean" use="optional" default="false"/>
        </xsd:complexType>
    </xsd:element>

    <xsd:complexType name="PropertyBase" abstract="true">
        <xsd:annotation>
            <xsd:appinfo>
                <jaxb:class name="DummyPropertyBase" implClass="com.mbm.properties.baseclasses.PropertyBase"/>
            </xsd:appinfo>
        </xsd:annotation>
    </xsd:complexType>
    
    <xsd:complexType name="PropertyType" abstract="true">
        <xsd:complexContent>
            <xsd:extension base="PropertyBase">
                <xsd:sequence>
                    <xsd:element name="description" type="descriptionType" minOccurs="0" maxOccurs="unbounded"/>
                    <xsd:element name="forValues" type="forValueType" minOccurs="0" maxOccurs="unbounded"/>
                </xsd:sequence>
                <xsd:attribute name="type" use="required">
                    <xsd:simpleType>
                        <xsd:restriction base="xsd:token">
                            <xsd:enumeration value="integer"/>
                            <xsd:enumeration value="float"/>
                            <xsd:enumeration value="boolean"/>
                            <xsd:enumeration value="string"/>
                        </xsd:restriction>
                    </xsd:simpleType>
                </xsd:attribute>
                <xsd:attribute name="name" type="xsd:string" use="required"/>
                <xsd:attribute name="required" type="xsd:boolean" use="optional" default="false"/>
                <xsd:attribute name="alias" type="xsd:string" use="optional"/>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>
    
    <xsd:complexType name="keywordPropertiesType">
        <xsd:sequence>
            <xsd:element name="keyword-property" type="keywordPropertyType" minOccurs="1" maxOccurs="unbounded">
                <xsd:annotation>
                    <xsd:appinfo>
                        <jaxb:property name="listOfKeywordProperties"/>
                    </xsd:appinfo>
                </xsd:annotation>
            </xsd:element>
        </xsd:sequence>
    </xsd:complexType>
    
    <xsd:complexType name="keywordPropertyType">
        <xsd:complexContent>
            <xsd:extension base="PropertyType">
                <xsd:sequence>
                    <xsd:element name="challenges" type="ChallengeType" minOccurs="0" maxOccurs="unbounded"/>
                </xsd:sequence>
                <xsd:attribute name="default-value" type="xsd:string" use="optional"/>
                <xsd:attribute name="valid-values" type="xsd:string" use="optional"/>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>

    <xsd:complexType name="positionalPropertiesType">
        <xsd:sequence>
            <xsd:element name="positional-property" type="positionalPropertyType" minOccurs="1" maxOccurs="unbounded">
                <xsd:annotation>
                    <xsd:appinfo>
                        <jaxb:property name="listOfPositionalProperties"/>
                    </xsd:appinfo>
                </xsd:annotation>
            </xsd:element>
        </xsd:sequence>
    </xsd:complexType>

    <xsd:complexType name="positionalPropertyType">
        <xsd:complexContent>
            <xsd:extension base="PropertyType"/>
        </xsd:complexContent>
    </xsd:complexType>
    
    <xsd:complexType name="ForValueBase" abstract="true">
        <xsd:annotation>
            <xsd:appinfo>
                <jaxb:class name="DummyForValueBase" implClass="com.mbm.properties.baseclasses.ForValueBase"/>
            </xsd:appinfo>
        </xsd:annotation>
    </xsd:complexType>
    
    <xsd:complexType name="forValueType">
        <xsd:complexContent>
            <xsd:extension base="ForValueBase">
                <xsd:sequence>
                    <xsd:element name="description" type="descriptionType" minOccurs="0" maxOccurs="unbounded"/>
                </xsd:sequence>
                <xsd:attribute name="value" type="xsd:string" use="required"/>
                <xsd:attribute name="implies" type="xsd:string" use="optional"/>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>
    
    <xsd:complexType name="descriptionType">
        <xsd:simpleContent>
            <xsd:extension base="xsd:string">
                <xsd:attribute name="reformat" type="xsd:boolean" use="optional" default="true"/>
                <xsd:attribute name="includeImplies" type="xsd:boolean" use="optional" default="true"/>
            </xsd:extension>
        </xsd:simpleContent>
    </xsd:complexType>

    <xsd:complexType name="ChallengeBase" abstract="true">
        <xsd:annotation>
            <xsd:appinfo>
                <jaxb:class name="DummyChallengeBase" implClass="com.mbm.properties.baseclasses.ChallengeBase"/>
            </xsd:appinfo>
        </xsd:annotation>
    </xsd:complexType>
    
    <xsd:complexType name="ChallengeType" abstract="true">
        <xsd:complexContent>
            <xsd:extension base="ChallengeBase">
                <xsd:attribute name="forValue" type="xsd:string"/>
                <xsd:attribute name="instruction" type="xsd:string"/>
                <xsd:attribute name="passChallengeValue" type="xsd:string"/>
                <xsd:attribute name="failChallengeValue" type="xsd:string" use="optional"/>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>

    <xsd:complexType name="MutualPropertiesType">
        <xsd:sequence>
            <xsd:element name="mutual-property-set" type="MutualPropertySetType" minOccurs="1" maxOccurs="unbounded"/>
        </xsd:sequence>
    </xsd:complexType>

    <xsd:complexType name="MutualPropertySetBase" abstract="true">
        <xsd:annotation>
            <xsd:appinfo>
                <jaxb:class name="DummyMutualPropertySetBase" implClass="com.mbm.properties.baseclasses.MutualPropertySetBase"/>
            </xsd:appinfo>
        </xsd:annotation>
    </xsd:complexType>

    <xsd:complexType name="MutualPropertySetType">
        <xsd:complexContent>
            <xsd:extension base="MutualPropertySetBase">
                <xsd:sequence>
                    <xsd:element name="mutual-property" type="mutualPropertyType" minOccurs="1" maxOccurs="unbounded"/>
                </xsd:sequence>
                <xsd:attribute name="type" use="required">
                    <xsd:simpleType>
                        <xsd:restriction base="xsd:token">
                            <xsd:enumeration value="inclusive"/>
                            <xsd:enumeration value="exclusive"/>
                        </xsd:restriction>
                    </xsd:simpleType>
                </xsd:attribute>
                <xsd:attribute name="name" type="xsd:string" use="optional"/>
            </xsd:extension>
        </xsd:complexContent>
    </xsd:complexType>

    <xsd:complexType name="mutualPropertyType">
        <xsd:attribute name="name" type="xsd:string" use="required"/>
        <xsd:attribute name="value" type="xsd:string" use="optional"/>
    </xsd:complexType>
</xsd:schema>
Run Code Online (Sandbox Code Playgroud)

XJC 生成的ObjectClass. 请注意,这缺少任何@XmlElementDecl属性。

// This file was generated by the Eclipse Implementation of JAXB, v3.0.2 
// See https://eclipse-ee4j.github.io/jaxb-ri 
// Any modifications to this file will be lost upon recompilation of the source schema. 
// Generated on: 2022.01.26 at 10:38:30 AM PST 
//


package com.mbm.properties.jaxb;

import jakarta.xml.bind.annotation.XmlRegistry;


/**
 * This object contains factory methods for each 
 * Java content interface and Java element interface 
 * generated in the com.mbm.properties.jaxb package. 
 * <p>An ObjectFactory allows you to programatically 
 * construct new instances of the Java representation 
 * for XML content. The Java representation of XML 
 * content can consist of schema derived interfaces 
 * and classes representing the binding of schema 
 * type definitions, element declarations and model 
 * groups.  Factory methods for each of these are 
 * provided in this class.
 * 
 */
@XmlRegistry
public class ObjectFactory {


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

    /**

S. *_*Kom 4

您在 Main 类中使用javax.xml.bind.Unmarshaller中的解组器,但生成的类使用包jakarta.xml.bind.*中的注释。这种不匹配在我的例子中导致了一个非常相似的错误。

修改后重新编译试试

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
Run Code Online (Sandbox Code Playgroud)

import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.Unmarshaller;
Run Code Online (Sandbox Code Playgroud)

在你的主课上。