javax.xml.bind.UnmarshalException:意外元素。预期元素是(无)
Posted
技术标签:
【中文标题】javax.xml.bind.UnmarshalException:意外元素。预期元素是(无)【英文标题】:javax.xml.bind.UnmarshalException: unexpected element. Expected elements are (none) 【发布时间】:2014-01-02 09:59:27 【问题描述】:我在解组字符串时收到此错误。我已经使用 JAXB 创建了 Java 文件。
JAXBContext jaxbContext = JAXBContext.newInstance(DocumentType.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
// Input string posted below
DocumentType dType = (DocumentType) unmarshaller.unmarshal(new StringReader("input string"));
堆栈跟踪:
Exception in thread "main" javax.xml.bind.UnmarshalException: unexpected element (uri:"http://ocrsdk.com/schema/recognizedBusinessCard-1.0.xsd", local:"document"). Expected elements are (none)
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)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(UnmarshallingContext.java:1048)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:483)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:465)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:135)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:506)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:376)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl$NSContentDriver.scanRootElementHook(XMLNSDocumentScannerImpl.java:602)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3065)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:881)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:607)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:116)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:489)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:835)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:764)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:123)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1210)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:568)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:203)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:175)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157)
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:214)
at JaxbTest.main(JaxbTest.java:19)
XSD:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://ocrsdk.com/schema/recognizedBusinessCard-1.0.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://ocrsdk.com/schema/recognizedBusinessCard-1.0.xsd"
elementFormDefault="qualified">
<xs:element name="document" type="tns:documentType"></xs:element>
<xs:complexType name="documentType">
<xs:sequence>
<xs:element name="businessCard" type="tns:businessCardType" minOccurs="0" maxOccurs="1"></xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="businessCardType">
<xs:sequence>
<xs:element name="field" type="tns:fieldType" minOccurs="0" maxOccurs="unbounded"></xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="fieldType">
<xs:sequence>
<xs:element name="value" type="xs:string" minOccurs="1" maxOccurs="1">
</xs:element>
<xs:element name="characters" type="tns:charactersType" minOccurs="0" maxOccurs="1"></xs:element>
<xs:element name="fieldComponents" type="tns:fieldComponentsType" minOccurs="0" maxOccurs="1"></xs:element>
</xs:sequence>
<xs:attribute name="type" type="tns:typeType"></xs:attribute>
</xs:complexType>
<xs:simpleType name="typeType">
<xs:restriction base="xs:string">
<xs:enumeration value="Name"></xs:enumeration>
<xs:enumeration value="Phone"></xs:enumeration>
<xs:enumeration value="Mobile"></xs:enumeration>
<xs:enumeration value="Fax"></xs:enumeration>
<xs:enumeration value="Company"></xs:enumeration>
<xs:enumeration value="Job"></xs:enumeration>
<xs:enumeration value="Address"></xs:enumeration>
<xs:enumeration value="Email"></xs:enumeration>
<xs:enumeration value="Web"></xs:enumeration>
<xs:enumeration value="Text"></xs:enumeration>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="charactersType">
<xs:sequence>
<xs:element name="char" type="tns:charType" minOccurs="0" maxOccurs="unbounded"></xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="charType">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="suspicious" type="xs:boolean" use="optional"></xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="fieldComponentsType">
<xs:sequence>
<xs:element name="fieldComponent" type="tns:fieldComponentType" minOccurs="0" maxOccurs="unbounded"></xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="fieldComponentType">
<xs:sequence>
<xs:element name="value" type="xs:string" minOccurs="1" maxOccurs="1">
</xs:element>
</xs:sequence>
<xs:attribute name="type" type="tns:fieldComponentTypeType"></xs:attribute>
</xs:complexType>
<xs:simpleType name="fieldComponentTypeType">
<xs:restriction base="xs:string">
<xs:enumeration value="FirstName"></xs:enumeration>
<xs:enumeration value="MiddleName"></xs:enumeration>
<xs:enumeration value="LastName"></xs:enumeration>
<xs:enumeration value="ExtraName"></xs:enumeration>
<xs:enumeration value="PhonePrefix"></xs:enumeration>
<xs:enumeration value="PhoneCountryCode"></xs:enumeration>
<xs:enumeration value="PhoneCode"></xs:enumeration>
<xs:enumeration value="PhoneBody"></xs:enumeration>
<xs:enumeration value="PhoneExtension"></xs:enumeration>
<xs:enumeration value="ZipCode"></xs:enumeration>
<xs:enumeration value="Country"></xs:enumeration>
<xs:enumeration value="City"></xs:enumeration>
<xs:enumeration value="StreetAddress"></xs:enumeration>
<xs:enumeration value="JobPosition"></xs:enumeration>
<xs:enumeration value="JobDepartment"></xs:enumeration>
</xs:restriction>
</xs:simpleType>
</xs:schema>
输入字符串:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://ocrsdk.com/schema/recognizedBusinessCard-1.0.xsd http://ocrsdk.com/schema/recognizedBusinessCard-1.0.xsd" xmlns="http://ocrsdk.com/schema/recognizedBusinessCard-1.0.xsd">
<businessCard>
<field type="Phone">
<value>783-37-00</value>
</field>
<field type="Phone">
<value>783-37-01</value>
</field>
<field type="Fax">
<value>783-26-63</value>
</field>
<field type="Email">
<value>john_sm@abbyy.com</value>
</field>
<field type="Web">
<value>www.abbyy.com</value>
</field>
<field type="Address">
<value>Otradnaya str., 2b, bld.6, 127273, Moscow, Russia</value>
</field>
<field type="Name">
<value>John Smith</value>
</field>
<field type="Company">
<value>ABBYY Headquarters</value>
</field>
<field type="Job">
<value>Product Analyst</value>
</field>
<field type="Text">
<value>ABBYY ABBYY Headquarters John Smith Product Analyst ABBYY Headquarters Otradnaya str., 2b, bld.6, 127273, Moscow, Russia Tel: 783-37-00 Fax: 783-26-63 john_sm@abbyy.com www.abbyy.com </value>
</field>
</businessCard>
</document>
【问题讨论】:
【参考方案1】:在我们的例子中,我们收到 UnmarshalException 是因为下面指定了错误的 Java 包。一旦安装了正确的包,问题就解决了:
@Bean
public Unmarshaller tmsUnmarshaller()
final Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
jaxb2Marshaller
.setPackagesToScan("java.package.to.generated.java.classes.for.xsd");
return jaxb2Marshaller;
【讨论】:
【参考方案2】:此错误的原因之一是使用了 jdk 中的 jaxb 实现。我不确定为什么在非常简单的 xml 解析情况下会出现这样的问题。您可以使用来自公共 maven 存储库的最新版本的 jaxb 库:
http://mvnrepository.com
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.2.12</version>
</dependency>
【讨论】:
【参考方案3】:当您从 XML Schema 生成 JAXB 模型时,对应于命名复杂类型的全局元素会将元数据捕获为 ObjectFactory
类中的 create 方法上的 @XmlElementDecl
注释。由于您仅在 DocumentType
类上创建 JAXBContext
,因此不会处理此元数据。如果您从 XML Schema 生成 JAXB 模型,那么您应该在生成的包名称或 ObjectFactory
类上创建 JAXBContext
,以确保处理所有必要的元数据。
示例解决方案:
JAXBContext jaxbContext = JAXBContext.newInstance(my.generatedschema.dir.ObjectFactory.class);
DocumentType documentType = ((JAXBElement<DocumentType>) jaxbContext.createUnmarshaller().unmarshal(inputStream)).getValue();
【讨论】:
工作正常。 unmarshaller.unmarshal() 将返回 JAXBElementunmarshaller = context.createUnmarshaller(); final Object object = unmarshaller.unmarshal(new File("path/to/data.xml")); final DocumentType cd = (DocumentType)object;
第二步如下:DocumentType doc = ((JAXBElement<DocumentType>) jaxbContext.createUnmarshaller().unmarshal( inputStream)).getValue();
我得到了和以前一样的错误。但是我可以使用这里建议的匿名根对象方法:***.com/a/15117152/1717259【参考方案4】:
或者,如果您想坚持使用DocumentType
类。
然后,您可以在 DocumentType 类的顶部添加以下注释。
@XmlRootElement(name="document")
注意:String值"document"
指的是xml消息的根标签的名称。
【讨论】:
谢谢,伙计。在为这种情况寻找解决方案大约几个小时后,@XmlRootElement 解决了这个问题。我想知道为什么这种行为应该是这样的。在解组过程中强制这个注释真的有意义吗? @Miere 现在我想起来了。在 Web 服务的世界中,RPC 样式自动提供了一个包装节点,而文档样式的 Web 服务需要显式声明。所以,这一直是一个讨论的领域。 我在 jdk1.6.0_45 中使用 xjc 从 XSD 生成 POJO。 xjc 生成的根 POJO 缺少 @XmlRootElement(name="RootName")。手动添加这一行,解组成功。 它始终是定义其关联的 xml 标记名称的所有者类(例如,使用@XmlElement(name='...')
)。因此,一个类没有定义自己的 xml 标记名称。但是由于根元素没有父节点,这给根元素带来了问题。 存在几种解决方案: XJC 假设您将使用它的ObjectFactory
。它使用ObjectFactory
中的@XmlElementDecl
注释定义根节点的名称。但是如果你不想使用ObjectFactory
,那么上面的注解(即@XmlRootElement
)可能是最简单的解决方案。
我也需要添加@XmlAccessorType(XmlAccessType.FIELD)
。以上是关于javax.xml.bind.UnmarshalException:意外元素。预期元素是(无)的主要内容,如果未能解决你的问题,请参考以下文章