本文介绍开发日常中遇到的将xml节点内容转换成java对象
问题
最近对接一个外部接口,接口中将文件信息以类似xml格式的形式通过某个字段返回,具体如下字段的字符串如下,我们需要从其中的节点取出对应的信息封装到java对象
<data>
<_result>
<Item>
<?xml version="1.0" encoding="UTF-8"?>
<Data>
<FileContent>ABCDdsads</FileContent>
<object_name>20230830100001082565.pdf</object_name>
</Data>
</Item>
</_result>
</data>
解决
1、maven依赖需要添加
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
2、相关知识
有几个关键的注解
@XmlRootElement:用于类上,表示该类是一个可以映射为XML文档的根元素。
@XmlElement:用于类上,表示该类是一个可以映射为XML文档的根元素。
@XmlTransient:用于类、字段和方法上,表示JAXB在映射XML元素时忽略被注解的类、字段、get/set对应字段。
@XmlAccessorType:用于包和类级别上,表示控制字段是否被默认序列化。
3、测试代码
下列是代码编写,可以直接运行但是还是会提示错误
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import java.io.StringReader;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
public static void main(String[] args) {
String xmlString = "<data><_result><Item><?xml version=\"1.0\" encoding=\"UTF-8\"?><Data><FileContent>ABCD</FileContent><object_name>20230830100001082565.pdf</object_name></Data></Item></_result></data>";
// String xmlString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><data><_result><Item><Data><FileContent>ABCD</FileContent><object_name>20230830100001082565.pdf</object_name></Data></Item></_result></data>";
try {
JAXBContext jaxbContext = JAXBContext.newInstance(Data1.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
StringReader reader = new StringReader(xmlString);
Data1 data1 = (Data1) jaxbUnmarshaller.unmarshal(reader);
System.out.println(data1);
System.out.println(JSON.toJSONString(data1));
// Now you can access the data in the 'data' object.
} catch (JAXBException e) {
e.printStackTrace();
}
}
@ToString
@Setter
@XmlRootElement(name = "data")
public static class Data1 {
@XmlElement(name = "_result")
private Result1 result;
}
@ToString
@Setter
public static class Result1 {
@XmlElement(name = "Item")
private Item item;
}
@ToString
@Setter
public static class Item {
@XmlElement(name = "Data")
private Data data;
}
@ToString
@Setter
public static class Data {
@XmlElement(name = "FileContent")
private String fileContent;
@XmlElement(name = "object_name")
private String objectName;
}
执行结果
执行上面的代码会抛异常
javax.xml.bind.UnmarshalException- with linked exception:
[org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 27; 不允许有匹配 “[xX][mM][lL]” 的处理指令目标。]
错误原因分析:
问题在于XML字符串中标签内部包含了一个XML声明(<?xml version="1.0" encoding="UTF-8"?>)。XML声明应该只出现在XML文档的开始,不能在文档的中间部分。
解决办法:
只需要将XML声明移动到XML字符串的开始,或者完全删除它。以下是修改后的XML字符串:
String xmlString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><data><_result><Item><Data><FileContent>ABCD</FileContent><object_name>20230830100001082565.pdf</object_name></Data></Item></_result></data>";
或者
String xmlString = "<data><_result><Item><Data><FileContent>ABCD</FileContent><object_name>20230830100001082565.pdf</object_name></Data></Item></_result></data>";
这样修改后,代码就能正常运行了。