解析XML/解析请求接口过来的XML (String字符串,非文件)
解析XML文本内容
- 现在常用的请求数据反馈都是JSON类型,但是请求相对较老的程序反馈的是XML内容,所以需要进行解析操作
- 我使用的spring boot项目 版本为:2.3.1.RELEASE
第一种:直接转JSON
这是也是通过别人的方式找到的,但是最终没有使用!
1.层级多比较杂就无法解析全部(根本舍弃原因)
2.格式必须规范
所以推荐 简单的xml解析 和使用JSON的人
<!-- JSON解析工具 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.59</version>
</dependency>
<!--解析XML配置-->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<!--这个可以不加,因为我这个版本和dom4j有版本冲突,如果为了轻量可尝试不加-->
<dependency>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
<version>1.4.01</version>
</dependency>
工具类
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.dom4j.*;
import java.util.List;
/**
* @program: cscocutil
* @description: xml
* @author: yzy
* @create: 2021-01-22 09:43
* @Version 1.0
**/
public class XmlCustom {
/**
* String 转 org.dom4j.Document
* @param xml
* @return
* @throws DocumentException
*/
public static Document strToDocument(String xml){
try {
//加上xml标签是为了获取最外层的标签,如果不需要可以去掉
return DocumentHelper.parseText("<xml>"+xml+"</xml>");
} catch (DocumentException e) {
return null;
}
}
/**
* org.dom4j.Document 转 com.alibaba.fastjson.JSONObject
* @param xml
* @return
* @throws DocumentException
*/
public static JSONObject documentToJSONObject(String xml){
return elementToJSONObject(strToDocument(xml).getRootElement());
}
/**
* org.dom4j.Element 转 com.alibaba.fastjson.JSONObject
* @param node
* @return
*/
public static JSONObject elementToJSONObject(Element node) {
JSONObject result = new JSONObject();
// 当前节点的名称、文本内容和属性
List<Attribute> listAttr = node.attributes();// 当前节点的所有属性的list
for (Attribute attr : listAttr) {// 遍历当前节点的所有属性
result.put(attr.getName(), attr.getValue());
}
// 递归遍历当前节点所有的子节点
List<Element> listElement = node.elements();// 所有一级子节点的list
if (!listElement.isEmpty()) {
for (Element e : listElement) {// 遍历所有一级子节点
if (e.attributes().isEmpty() && e.elements().isEmpty()) // 判断一级节点是否有属性和子节点
result.put(e.getName(), e.getTextTrim());// 沒有则将当前节点作为上级节点的属性对待
else {
if (!result.containsKey(e.getName())) // 判断父节点是否存在该一级节点名称的属性
result.put(e.getName(), new JSONArray());// 没有则创建
((JSONArray) result.get(e.getName())).add(elementToJSONObject(e));// 将该一级节点放入该节点名称的属性对应的值中
}
}
}
return result;
}
}
调用方式
public static void main(String[] args) {
String xml = "<test>测试</test>";
XmlCustom.documentToJSONObject(xml);
}
第二种:使用DOM4J这种方式(推荐)
这种方式相当于原生方式
自定义高,可以应对各种复杂XML。但是通用性不佳
<?xml version="1.0" encoding="utf-8"?>
<msg action="web" brief="测试" >
<item bg="1">
<title>你收到信息</title>
</item>
<item>
<summary back="#000" >2021-01-21</summary>
</item>
<item>
<summary back="#000000">测试1</summary>
</item>
<item>
<summary back="#000000">测试2</summary>
</item>
<item>
<hr/>
<more>详情</more>
</item>
</msg>
以下拟定了一写常用的调用方式,可以结合上方 xml 参考
//解析 XML
public void dom4jXml(String xml) {
System.out.println(xml);
try {
//解析 XML
Document xmlDocument = DocumentHelper.parseText(xml);
//获取根路径
Element rootElement = xmlDocument.getRootElement();
//获取标签名:返回msg
System.out.println(rootElement.getName());
//获取标签里的内容 这个根目录没有 返回 null
System.out.println(rootElement.getText());
/** 获取全部标签体内容 */
List<Attribute> attributes = rootElement.attributes();
for (Attribute attribute : attributes) {
//获取 名称 action 、 brief
System.out.println(attribute.getName());
//获取 名称 web 、 测试
System.out.println(attribute.getValue());
}
/** 获取指定标签体内容*/
Attribute brief = rootElement.attribute("brief");
//获取 名称 brief
System.out.println(brief.getName());
//获取 名称 测试
System.out.println(brief.getValue());
getElement(rootElement);
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 反馈节点所有内容
* 递归 获取全部
* @param node
*/
public void getElement(Element node) {
//返回名称
System.out.println(node.getName());
//返回标签里的内容 getTextTrim(同)
System.out.println(node.getText());
/** 获取全部标签体内容 */
List<Attribute> attributes = node.attributes();
for (Attribute attribute : attributes) {
//获取 名称 action 、 brief
System.out.println(attribute.getName());
//获取 名称 web 、 测试
System.out.println(attribute.getValue());
}
/** 递归当前字节电所有内容 */
List<Element> elements = node.elements();
for (Element element : elements) {
getElement(element);
}
}
关于如何获取 文件.xml
// 创建一个SAXReader对象
SAXReader sax = new SAXReader();
// 根据指定的路径创建file对象
File xmlFile = new File("路径");
// 获取document对象,如果文档无节点,则会抛出Exception提前结束
Document document = sax.read(xmlFile);
// 获取根节点
Element root = document.getRootElement();
其中spring boot在不引入任何插件的情况下,是可以直接获取xml文件的内容的。并且很方便。