在日常开发中常见的XML解析方式有如下两种
????????要求解析器将整个XML文件全部加载到内存中,生成一个Document对象
????????????????1.优点:元素和元素之间保留结构、关系,可以针对元素进行增删查改操作
????????????????2.缺点:如果XML文件过大,可能会导致内存溢出
????????是一种速度更快,更加高效的解析方式。它是逐行扫描,边扫描边解析,并且以事件驱动的方式来进行具体的解析,每解析一行都会触发一个事件
????????????????1.优点:不会出现内存溢出的问题,可以处理大文件
????????????????2.缺点:只能读,不能写
????????解析器就是根据不同的解析方式提供具体的实现,为了方便开发人员来解析XML,有一些方便操作的类库。
dom4j:比较简单的XML解析的类库
Jsoup:功能强大的DOM方式解析的类库,尤其对HTML的解析更加方便
????????org.dom4j.Document常用方法
Element getRootElement();//获取xML文件的根节点
????????org.dom4j.Element的常用方法
String getName(); //返回标签的名称
List<Element> elements(); //获取标签的子标签
String attributeValue(String name);//获取指定属性名称的属性值
String getText();//获取标签的文本
String elementText(Stringname);//获取措定名称的子标签的文本
package com.itheima.demo.dom4j;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.util.List;
/**
* dom4j解析用户xml测试
*
* @author YZH
* @date 2023/12/20
*/
public class Dom4jParseUserXmlTest {
public static void main(String[] args) {
// 创建解析器对象
SAXReader saxReader = new SAXReader();
try {
// 一定要注意路径!!!吃过亏
Document document = saxReader.read(Dom4jParseUserXmlTest.class.getClassLoader().getResource("static/user.xml"));
Element rootElement = document.getRootElement();
System.out.println("1.----->user.xml根节点名字:"+rootElement.getName());
System.out.println("------------------------");
System.out.println("2.----->获取根标签users的子标签列表");
List<Element> usersSubElementList = rootElement.elements();
for (Element userElement : usersSubElementList) {
System.out.println("users标签的子标签的名字是:"+userElement.getName());
System.out.println("users标签的子标签的id属性值是:"+userElement.attributeValue("id"));
System.out.println("users标签的子标签的country属性值是:"+userElement.attributeValue("country"));
System.out.println("------------------");
System.out.println("3.----->获取user的子标签列表");
List<Element> userSubElementList = userElement.elements();
for (Element userSubelement : userSubElementList) {
System.out.println("user标签下的子标签名字是:"+userSubelement.getName());
System.out.println("user标签下的子标签文本是:"+userSubelement.getText());
}
}
// 获取users标签的第一个user标签
Element firstUserElement = rootElement.element("user");
// 第一个user标签的子标签password文本
String password = firstUserElement.elementText("password");
System.out.println(password);
} catch (DocumentException e) {
e.printStackTrace();
}
}
}
1.----->user.xml根节点名字:users
------------------------
2.----->获取根标签users的子标签列表
users标签的子标签的名字是:user
users标签的子标签的id属性值是:TB10001
users标签的子标签的country属性值是:Chinese
------------------
3.----->获取user的子标签列表
user标签下的子标签名字是:id
user标签下的子标签文本是:10001
user标签下的子标签名字是:name
user标签下的子标签文本是:admin
user标签下的子标签名字是:password
user标签下的子标签文本是:111111
user标签下的子标签名字是:salary
user标签下的子标签文本是:salary > 15000 & salary < 30000
users标签的子标签的名字是:user
users标签的子标签的id属性值是:TB10002
users标签的子标签的country属性值是:Chinese
------------------
3.----->获取user的子标签列表
user标签下的子标签名字是:id
user标签下的子标签文本是:10002
user标签下的子标签名字是:name
user标签下的子标签文本是:tonny
user标签下的子标签名字是:password
user标签下的子标签文本是:666666
user标签下的子标签名字是:salary
user标签下的子标签文本是:salary > 15000 & salary < 3000
111111
进程已结束,退出代码为 0
XPath可以使用路径表达式来选取XML文档中的元素或者属性节点,节点是沿着路径来选取的。
XPath的官方文档地址XPath 教程 (zvon.org)
maven下载依赖
<!-- https://mvnrepository.com/artifact/jaxen/jaxen -->
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>2.0.0</version>
</dependency>
Document/Element关于XPath的api
????????
Node selectSingleNode(String xpathExpression); //根据xPath表达式获取单个标签(元素/节点)
List<Node> selectNodes(String xpathExpression); //根据xPath表达式获取多个标签(元素/节点)
package com.itheima.demo.dom4j;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import java.util.List;
public class Dom4jXPathParseUserXmlTest {
public static void main(String[] args) {
SAXReader saxReader = new SAXReader();
try {
Document document = saxReader.read(Dom4jParseUserXmlTest.class.getClassLoader().getResource("user.xml"));
System.out.println("1.------>使用绝对路径方式查找元素");
// Node继承Element,也可以换一种写法
// Node selectSingleNode = document.selectSingleNode("/users/user/password");
Element element = (Element)document.selectSingleNode("/users/user/password");
// 获取密码
String password = element.getText();
System.out.println("第一个用户的密码是:"+password);
System.out.println("2.------>使用相对路径方式查找元素");
Element node =(Element) element.selectSingleNode("../salary");
System.out.println(node.getText());
System.out.println("3.------>使用相对路径方式查找元素");
System.out.println("获取所有ID元素的文本");
List<Node> idNodeList = document.selectNodes("//id");
for (Node node1 : idNodeList) {
Element idElement = (Element) node1;
System.out.println(idElement.getText());
}
System.out.println("4.------>谓语(条件筛选)方式查找元素");
System.out.println("获取user id属性为TB10001的用户属性信息");
Element TB10001IDElement = (Element)document.selectSingleNode("//user[@id='TB10001']");
List<Element> elementList = TB10001IDElement.elements();
for (Element userSubElement : elementList) {
System.out.println("user子标签的名称"+userSubElement.getName());
System.out.println("user子标签的文本"+userSubElement.getText());
}
} catch (DocumentException e) {
throw new RuntimeException(e);
}
}
}
C:\Users\YZH\.jdks\openjdk-17.0.1\bin\java.exe "-javaagent:D:\IDEA\IntelliJ IDEA 2023.1\lib\idea_rt.jar=63970:D:\IDEA\IntelliJ IDEA 2023.1\bin" -Dfile.encoding=UTF-8 -classpath D:\黑马下半\huizhi-learning\maven_java\target\test-classes;D:\黑马下半\huizhi-learning\maven_java\target\classes;D:\maven-repository\org\junit\jupiter\junit-jupiter-api\5.9.2\junit-jupiter-api-5.9.2.jar;D:\maven-repository\org\opentest4j\opentest4j\1.2.0\opentest4j-1.2.0.jar;D:\maven-repository\org\junit\platform\junit-platform-commons\1.9.2\junit-platform-commons-1.9.2.jar;D:\maven-repository\org\apiguardian\apiguardian-api\1.1.2\apiguardian-api-1.1.2.jar;D:\maven-repository\org\dom4j\dom4j\2.1.4\dom4j-2.1.4.jar;D:\maven-repository\jaxen\jaxen\2.0.0\jaxen-2.0.0.jar com.itheima.demo.dom4j.Dom4jXPathParseUserXmlTest
1.------>使用绝对路径方式查找元素
第一个用户的密码是:111111
2.------>使用相对路径方式查找元素
salary > 15000 & salary < 30000
3.------>使用相对路径方式查找元素
获取所有ID元素的文本
10001
10002
4.------>谓语(条件筛选)方式查找元素
获取user id属性为TB10001的用户属性信息
user子标签的名称id
user子标签的文本10001
user子标签的名称name
user子标签的文本admin
user子标签的名称password
user子标签的文本111111
user子标签的名称salary
user子标签的文本salary > 15000 & salary < 30000
进程已结束,退出代码为 0
<?xml version="1.0" encoding="utf-8" ?>
<!--<!DOCTYPE users SYSTEM "user.dtd">-->
<users>
<user id ="TB10001" country="Chinese">
<id>10001</id>
<name>admin</name>
<password>111111</password>
<!-- &用&替代,<用<替代-->
<salary>salary > 15000 & salary < 30000</salary>
</user>
<user id ="TB10002" country="Chinese" source="PC">
<id>10002</id>
<name>tonny</name>
<password>666666</password>
<!-- &用&替代,<用<替代-->
<salary>salary > 15000 & salary < 3000</salary>
</user>
</users>