原文: https://howtodoinjava.com/jaxb/unmarshal-without-xmlrootelement/
很多时候,您将需要解组不具有诸如@XmlRootElement之类的 JAXB 注解的 Java 对象,并且不允许您对源代码进行任何更改。 当您使用旧代码或某些您没有源代码的客户端 jar 时,可能会发生这种情况。
1.不带 JAXB 注解的解组问题
在这种情况下,如果您尝试直接将 Java 对象解组为 XML ,则将出现类似的错误。
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 注解。
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@Overridepublic String toString() {return "Employee [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", department="+ department + "]";}}
2.不带 JAXB 注解的解组解决方案
缺少@XmlRootElement注解时,JAXB 无法为Employee对象构建JAXBElement实例。 因此,您必须在此帮助 JAXB 手动构建它。
2.1 语法
/*** 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;
例如:
JAXBElement<Employee> jaxbElement = (JAXBElement<Employee>) jaxbUnmarshaller.unmarshal(new StreamSource(xmlFile), Employee.class);
2.2 解组
现在,让我们看看该解组代码的工作方式。
<?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>
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();}}}
程序输出:
Employee [id=1, firstName=Lokesh, lastName=Gupta, department=Department [id=101, name=IT]]
将我的问题放在评论部分。
学习愉快!
