原文: 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
@Override
public 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]]
将我的问题放在评论部分。
学习愉快!