XML规范统一,与操作系统、编程语言的开发平台无关。
在存储数据、交换数据、数据配置方面有优势。
格式如下
<?xml version="1.0" encoding="UTF-8"?>
<books>
<!--图书信息 -->
<book id="101">
<author>明日科技</author>
<title>Java从入门到精通</title>
<description>零基础入门,适合自学</description>
</book>
<book id="102">
<author>关东升</author>
<title>Java从小白到大牛</title>
<description>Oracle公司官方推荐用书</description>
</book>
</books>
XML元素:由开始标签、元素内容和标签组成。元素内容可以包含子元素、字符数据等。
解析XML技术
1、DOM 基于XML树结构、比较耗资源、适用于多次访问XML
2、SAX 基于事件,消耗资源小,适用于数据量较大的XML
3、JDOM 比DOM更快,仅使用具体类而不使用接口
4、DOM4J 非常优秀的Java XML API 使用最多??
DOM解析XML
DOM是Document Object Model即文档对象模型的简称。
DOM把XML文档映射成一个倒挂的树。
Dom4J是一个易用的、开源的库,用于XML,XPath和XSLT。它应用于Java平台,采用了Java集合框架并完全支持DOM,SAX和JAXP。?
甲骨文公司提供了JAXP(Java API for XML Processing)来解析XML。
JAXP会把XML文档转换成一个DOM树。
JAXP包含3个包,这3个包都在JDK中:
org.w3c.dom:W3C推荐的用于使用DOM解析XML文档的接口。
org.xml.sax:用于使用SAX解析XML文档的接口。
javax.xml.parsers:解析器工厂工具,程序员获得并配置特殊的解析器。
Document接口:Document对象代表整个XML文档,它也是对XML文档进行操作的起点。
Document接口继承自Node接口
常用方法 | 方法说明 |
Element createElement(String tagName) | 创建指定标记名称的元素。 |
Element getDocumentElement() | 获取代表XML文档根元素的对象。 |
NodeList getElementsByTagName(String tagName) | 按文档顺序返回文档中指定标记名称 的所有元素集合 |
org.w3c.dom包中的常用接口
Node接口:表示树中的一个抽象节点。
?
常用方法 | 方法说明 |
Node appendChild(Node newChild) | 将节点 newChild 添加到此节点的子节点列表的末尾。 |
NodeList getChildNodes() | 获取该元素的所有子节点,返回节点的列表。 |
Node getFirstChild() | 此节点的第一个子节点。 |
Node getLastChild() | 此节点的最后一个节点。 |
Node getParentNode() | 此节点的父节点。 |
String getNodeName() | 获取节点的名称。 |
String getTextContent() | 此属性返回此节点及其后代的文本内容。 |
Node removeChild(Node newChild) | 从子节点列表中移除 oldChild 所指示的子节点,并将其返回。 |
?org.w3c.dom包中的常用接口
NodeList接口:包含了一个或者多个节点的列表。
常用方法 | 方法说明 |
int getLength (String tagName) | 返回列表的长度。 |
Node item(int index) | 返回集合中的第 index 个项。如果 index 大于或等于此列表中的节点数,则返回 null。 |
org.w3c.dom包中的常用接口4-4
Element接口:代表XML文档中的标签元素。
Element接口继承自Node,也是Node最主要的子对象。在标签中可以包含属性。
常用方法 | 方法说明 |
String getAttribute(String name) | 通过名称获得属性值。 |
Attr getAttributeNode(String name) | 通过名称获得属性节点。 |
NodeList getElementsByTagName(String tagName) | 以文档顺序返回具有给定标记名称的所有后代 Elements 的 NodeList。 |
void setAttribute(String name, String value) | 添加一个新属性。 |
常用接口
接口名 | 说明 |
Attribute | 定义了 XML 的属性。 |
Document | 定义了XML 文档。 |
Element | 定义了XML 元素。 |
Node | 为DOM4J中所有的XML节点定义了多态行为 |
XML增删改查实例
package com.kgc.day05.dom4j;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
import java.io.File;
/**
* @author: zjl
* @datetime: 2023/12/27
* @desc:
*/
public class Dom4jUtil {
public static Document createDocument(String xmlPath) {
//1.指定要解析的XML文件
File file = new File(xmlPath);
//2.创建文档对象模型
SAXReader sax = new SAXReader();
Document document = null;
try {
document = sax.read(file);
} catch (DocumentException e) {
//e.printStackTrace();
System.out.println("文档不存在!");
}
return document;
}
}
package com.kgc.day05.dom4j;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
import java.io.File;
/**
* @author: zjl
* @datetime: 2023/12/27
* @desc:
*/
public class Dom4jUtil {
public static Document createDocument(String xmlPath) {
//1.指定要解析的XML文件
File file = new File(xmlPath);
//2.创建文档对象模型
SAXReader sax = new SAXReader();
Document document = null;
try {
document = sax.read(file);
} catch (DocumentException e) {
//e.printStackTrace();
System.out.println("文档不存在!");
}
return document;
}
}
package com.kgc.day05.dom4j;
/**
* @author: zjl
* @datetime: 2023/12/27
* @desc:
*/
public class Member {
private String card;
private String name;
private String password;
private int count;
public Member() {
}
public Member(String card, String name, String password, int count) {
this.card = card;
this.name = name;
this.password = password;
this.count = count;
}
@Override
public String toString() {
return "Member{" +
"card='" + card + '\'' +
", name='" + name + '\'' +
", password='" + password + '\'' +
", count=" + count +
'}';
}
public String getCard() {
return card;
}
public void setCard(String card) {
this.card = card;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
package com.kgc.day05.dom4j;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* @author: zjl
* @datetime: 2023/12/27
* @desc:
*/
public class MemberDom4J {
//先创建一个空的Member集合,用来存储解析出来的每一个Member对象
List<Member> memberList = new ArrayList<>();
//解析XML文件
public void loadXml(String xmlPath) {
Document document = Dom4jUtil.createDocument(xmlPath);
if(document == null){
System.out.println("文档解析失败!");
return;
}
Member member = null;
//1.获取到根节点 members
Element rootElement = document.getRootElement();
//2.获取到根节点的所有子节点 每一个member元素
List<Element> memberEleList = rootElement.elements();
for (Element memberEle : memberEleList) {
//3.创建每一个member元素对应的Member对象
member = new Member();
//4.解析member元素的card属性值,并赋值给Member对象的card属性
member.setCard(memberEle.attributeValue("card"));
//直接从member元素中获取指定名称的子元素,如下面这个就是获取指定的name标签的文本内容,并赋值给Member的name属性
member.setName(memberEle.element("name").getText());
member.setPassword(memberEle.element("password").getText());
int count = 0;
try {
count = Integer.parseInt(memberEle.element("count").getText());
}catch (Exception e){}
member.setCount(count);
/*//5.解析member元素的所有子节点 name、password、count元素
List<Element> attrElementList = memberEle.elements();
for (Element attrEle : attrElementList) {
//6.获取member元素的子节点的元素名称/标签名称
String eleName = attrEle.getName();
//7.根据标签名称,将标签的文本内容赋值给对应的属性
switch (eleName){
case "name":
member.setName(attrEle.getText());
break;
case "password":
member.setPassword(attrEle.getText());
break;
case "count":
int count = 0;
try {
count = Integer.parseInt(attrEle.getText());
}catch (Exception e){}
member.setCount(count);
break;
}
}*/
//8.每解析玩一个member元素,就表示创建完了一个Member对象,将这个对象添加到事先准备好的集合中
memberList.add(member);
}
}
//添加一个Member对象
public void addMember(Member member){
Document document = Dom4jUtil.createDocument("files/xml/members.xml");
Element rootElement = document.getRootElement();
Element memberEle = rootElement.addElement("member");
memberEle.addAttribute("card",member.getCard());
memberEle.addElement("name").setText(member.getName());
memberEle.addElement("password").setText(member.getPassword());
memberEle.addElement("count").setText(member.getCount()+"");
saveXml(document,"files/xml/saveMember.xml");
}
//修改
public void updateMember(Member member){
Document document = Dom4jUtil.createDocument("files/xml/members.xml");
Element rootElement = document.getRootElement();
List<Element> memberEleList = rootElement.elements();
for (Element memberEle : memberEleList) {
if(memberEle.attributeValue("card").equals(member.getCard())){
memberEle.element("name").setText(member.getName());
memberEle.element("password").setText(member.getPassword());
memberEle.element("count").setText(member.getCount()+"");
break;
}
}
saveXml(document,"files/xml/updateMember.xml");
}
//修改
public void deleteMember(String card){
Document document = Dom4jUtil.createDocument("files/xml/members.xml");
Element rootElement = document.getRootElement();
List<Element> memberEleList = rootElement.elements();
for (Element memberEle : memberEleList) {
if(memberEle.attributeValue("card").equals(card)){
//rootElement.remove(memberEle);
memberEle.getParent().remove(memberEle);
break;
}
}
saveXml(document,"files/xml/deleteMember.xml");
}
public void saveXml(Document document ,String savePath){
//1.创建XMLWriter对象
XMLWriter xmlWriter = null;
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");
try {
xmlWriter = new XMLWriter(new FileWriter(savePath),format);
xmlWriter.write(document);
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(xmlWriter!=null){
xmlWriter.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void print() {
memberList.forEach(member -> {
System.out.println(member);
});
}
}