技术:
dom和sax解析的区别:
dom方式解析:
- 根据xml的层级结构在内存中分配一个树形结构,把xml的标签、属性、文本都封装成一个对象;
- 缺点:文件过大会造成内存溢出;
- 有点:方便实现增删改操作;
sax方式解析:
- 采用时间驱动,边读边解析;
- 从上到下,一行一行地解析,解析到某个对象(标签)则返回对象名称;
- 缺点:不能实现增删改操作:
- 优点:文件过大不会造成内存溢出,方便实现查询的操作;
解析器:
jaxp(sun公司)、dom4j(dom4j组织)【使用最多】、jdom(jom组织)
应用的Java包:javax.xml.parse
dom:
DocumentBuilder:解析器类
- 这个类是抽象类,不能new实例化:
这个类的实例可以从DocumentBuilderFactory.newDocumentBuilder()
方法获得
- 解析方法:
- 传入File(路径)对象:public Document parse(File f)throws SAXException,IOException
- 传入xml路径:public Document parse(String uri) throws SAXException,IOException
- 返回Document:public interface Document extends Node
- Document中的方法:
NodeListgetElementsByTagName(String tagname):
返回 NodeList所有的 Elements文档顺序与给定的标签名称,包含在文档中。
Element createElement(String tagName) throws DOMException:
创建指定类型的元素。请注意,返回的实例实现了Element接口,因此可以直接在返回的对象上指定属性。
Text createTextNode(String data):
创建给定指定字符串的 Text节点。
Node appendChild(Node newChild) throws DOMException:
将节点newChild添加到此节点的子节点列表的末尾。如果newChild已经在树中,那么它首先被删除。
Node removeChild(Node oldChild) throws DOMException:
通过删除指定的子节点 oldChild儿童的名单,并将其返回。
Node getParentNode():
得到这个节点的父节点
DocumentBuilderFactory:解析器工厂
- 这个类是抽象类,不能new实例化:
newInstance()
获得一个新的 DocumentBuilderFactory
实例,方法返回的是DocumentBuilderFactory类型。
sax:
SAXParser:解析器类
SAXParserFactory:解析器工厂
使用jaxp查询操作:
新建一个xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<person>
<p1>
<name>zhangsan</name>
<age>15</age>
<school>hope school</school>
</p1>
<p1>
<name>lisi</name>
<age>11</age>
<school>hope school</school>
</p1>
</person>
package jaxp.cn;
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* 实现jaxp查询操作
* @author CDU_LM
*
*/
public class JaxpDemo {
public static void main(String[] args) throws Exception {
// 查询xml所有name元素的值
/*
* 1、创建解析器工厂
* 2、根据解析器工厂创建解析器
* 3、解析xml返回document
* 4、得到所有的name元素
* */
// 创建解析器工厂
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// 创建解析器
DocumentBuilder builder = dbf.newDocumentBuilder();
// 解析xml返回document
Document document = builder.parse("src" + File.separator + "Person.xml");
NodeList list = document.getElementsByTagName("name");
// 遍历list
for (int i = 0; i < list.getLength(); i++) {
Node name = list.item(i); // 得到每一个name元素
String str = name.getTextContent(); // 得到name元素里面的值
System.out.println(str);
}
}
}
输出结果:
添加一个查询元素指定位置值的方法:
public static void selectOne() throws Exception{
// 查询xml所有name元素的值
/*
* 1、创建解析器工厂
* 2、根据解析器工厂创建解析器
* 3、解析xml返回document
* 4、得到所有的name元素
* */
// 创建解析器工厂
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// 创建解析器
DocumentBuilder builder = dbf.newDocumentBuilder();
// 解析xml返回document
Document document = builder.parse("src" + File.separator + "Person.xml");
NodeList list = document.getElementsByTagName("name"); // 得到元素列表
// 取出list第一个元素
Node name1 = list.item(0);
String str = name1.getTextContent(); // 得到元素值
System.out.println(str);
}
调用后输出结果:
这样就是获取到了name元素第一个位置的值。
创建添加节点的方法add():
方法中的步骤:
1、 创建解析器工厂
2、 创建解析器
3、 解析
4、 找到标签
5、 item()方法下标得到第一个p1
6、 创建sex标签
7、 创建文本
8、 把本文添加到sex下面
9、 把sex添加到第一个p1下面
以上操作是在内存中,需要将内容写入xml文档
1、 回写类的工厂类
2、 使用工厂类创建回写的类实例
3、 回写方法transform()
/**
* 在第一个p1标签下添加子标签
*/
public static void add() throws Exception {
// 创建解析器工厂
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// 创建解析器
DocumentBuilder builder = dbf.newDocumentBuilder();
// 解析
Document doc = builder.parse("src" + File.separator + "Person.xml");
// 找到标签
NodeList name = doc.getElementsByTagName("p1");
// item()方法下标得到第一个p1
Node p1 = name.item(0);
// 创建sex标签
Element sex = doc.createElement("sex");
// 创建文本
Text test = doc.createTextNode("NV");
// 把本文添加到sex下面
sex.appendChild(test);
// 把sex添加到第一个p1下面
p1.appendChild(sex);
// 以上操作是在内存中,需要将内容写入xml文档
// 回写类的工厂类
TransformerFactory tff = TransformerFactory.newInstance();
// 回写的类实例
Transformer tf = tff.newTransformer();
// 回写方法transform()
tf.transform(new DOMSource(doc), new StreamResult("src" + File.separator + "Person.xml"));
}
添加成功
创建修改标签文本方法modify():
/**
* 修改第一个p1标签下的sex标签的文本
*/
public static void modify() throws Exception {
// 创建解析器工厂
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// 创建解析器
DocumentBuilder builder = dbf.newDocumentBuilder();
// 解析
Document doc = builder.parse("src" + File.separator + "Person.xml");
// 找到标签
NodeList name = doc.getElementsByTagName("sex");
// 取出标签
Node sex = name.item(0);
// 修改标签中的文本
sex.setTextContent("nan");
// 以上操作是在内存中,需要将内容写入xml文档
// 回写类的工厂类
TransformerFactory tff = TransformerFactory.newInstance();
// 回写的类实例
Transformer tf = tff.newTransformer();
// 回写方法transform()
tf.transform(new DOMSource(doc), new StreamResult("src" + File.separator + "Person.xml"));
}
创建成功。
创建删除节点的方法remove():
/**
* 删除sex节点
*/
public static void remove() throws Exception{
// 创建解析器工厂
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// 创建解析器
DocumentBuilder builder = dbf.newDocumentBuilder();
// 解析
Document doc = builder.parse("src" + File.separator + "Person.xml");
// 找到标签
NodeList name = doc.getElementsByTagName("sex");
// 取出节点
Node sex = name.item(0);
// 得到sex的父节点
Node p1 = sex.getParentNode();
// 父节点删除其子节点
p1.removeChild(sex);
// 以上操作是在内存中,需要将内容写入xml文档
// 回写类的工厂类
TransformerFactory tff = TransformerFactory.newInstance();
// 回写的类实例
Transformer tf = tff.newTransformer();
// 回写方法transform()
tf.transform(new DOMSource(doc), new StreamResult("src" + File.separator + "Person.xml"));
}
删除成功。
遍历节点:
/**
* 递归遍历节点
*/
public static void listElement() throws Exception {
// 创建解析器工厂
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// 创建解析器
DocumentBuilder builder = dbf.newDocumentBuilder();
// 解析xml
Document doc = builder.parse("src" + File.separator + "Person.xml");
// 创建方法来遍历节点
list(doc);
}
public static void list(Node node) {
if (node.getNodeType() == Node.ELEMENT_NODE) { // 如果节点类型是一个元素元素
System.out.println(node.getNodeName());
}
// 得到一层子节点
NodeList list1 = node.getChildNodes();
for (int i = 0; i < list1.getLength(); i++) {
// 得到每一个节点
Node nodes = list1.item(i);
// 继续得到nodes的第一个节点
list(nodes);
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)