ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
# 不带 jaxb 注解的解组 > 原文: [https://howtodoinjava.com/jaxb/unmarshal-without-xmlrootelement/](https://howtodoinjava.com/jaxb/unmarshal-without-xmlrootelement/) 很多时候,您将需要**解组不具有诸如`@XmlRootElement`之类的 JAXB 注解**的 Java 对象,并且不允许您对源代码进行任何更改。 当您使用旧代码或某些您没有源代码的客户端 jar 时,可能会发生这种情况。 ## 1.不带 JAXB 注解的解组问题 在这种情况下,如果您尝试直接将[ Java 对象解组为 XML](https://howtodoinjava.com/jaxb/read-xml-to-java-object/) ,则将出现类似的错误。 ```java javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"employee"). 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) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:109) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(UnmarshallingContext.java:1131) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:556) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:538) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:153) at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:509) at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:379) at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl$NSContentDriver.scanRootElementHook(XMLNSDocumentScannerImpl.java:605) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3138) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:880) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606) at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:117) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777) at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141) at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213) at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:649) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:243) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:214) at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157) at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:162) at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:171) at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:189) at com.howtodoinjava.demo.JaxbExample.jaxbXmlFileToObject(JaxbExample.java:63) at com.howtodoinjava.demo.JaxbExample.main(JaxbExample.java:21) ``` 其中`Employee.java`类如下。 它没有任何`@XmlRootElement`这样的 JAXB 注解。 ```java package com.howtodoinjava.demo.model; import java.io.Serializable; public class Employee implements Serializable { private static final long serialVersionUID = 1L; private Integer id; private String firstName; private String lastName; private Department department; public Employee() { super(); } public Employee(int id, String fName, String lName, Department department) { super(); this.id = id; this.firstName = fName; this.lastName = lName; this.department = department; } //Getters and Setters @Override public String toString() { return "Employee [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", department=" + department + "]"; } } ``` ## 2.不带 JAXB 注解的解组解决方案 缺少`@XmlRootElement`注解时,JAXB 无法为`Employee`对象构建`JAXBElement`实例。 因此,您必须在此帮助 JAXB 手动构建它。 #### 2.1 语法 ```java /** * Unmarshal XML data from the specified XML Source by <tt>declaredType</tt> and return the * resulting content tree. * @param source source the XML Source to unmarshal XML data from (providers are * only required to support SAXSource, DOMSource, and StreamSource) * * @param declaredType appropriate JAXB mapped class to hold <tt>source</tt>'s xml root element * * @return value Java content rooted by JAXB Element */ public <T> JAXBElement<T> unmarshal( javax.xml.transform.Source source, Class<T> declaredType ) throws JAXBException; ``` 例如: ```java JAXBElement<Employee> jaxbElement = (JAXBElement<Employee>) jaxbUnmarshaller .unmarshal(new StreamSource(xmlFile), Employee.class); ``` #### 2.2 解组 现在,让我们看看该解组代码的工作方式。 ```java <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <employee> <department> <id>101</id> <name>IT</name> </department> <firstName>Lokesh</firstName> <id>1</id> <lastName>Gupta</lastName> </employee> ``` ```java package com.howtodoinjava.demo; import java.io.File; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; import javax.xml.transform.stream.StreamSource; import com.howtodoinjava.demo.model.Employee; public class JaxbExample { public static void main(String[] args) { String fileName = "employee.xml"; jaxbXmlFileToObject(fileName); } private static void jaxbXmlFileToObject(String fileName) { File xmlFile = new File(fileName); JAXBContext jaxbContext; try { jaxbContext = JAXBContext.newInstance(Employee.class); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); JAXBElement<Employee> jaxbElement = (JAXBElement<Employee>) jaxbUnmarshaller .unmarshal(new StreamSource(xmlFile), Employee.class); Employee employee = jaxbElement.getValue(); System.out.println(employee); } catch (JAXBException e) { e.printStackTrace(); } } } ``` 程序输出: ```java Employee [id=1, firstName=Lokesh, lastName=Gupta, department=Department [id=101, name=IT]] ``` 将我的问题放在评论部分。 学习愉快! 参考: [`XmlRootElement` Java 文档](https://docs.oracle.com/javase/7/docs/api/javax/xml/bind/annotation/XmlRootElement.html)