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;}@Overridepublic 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.获取到根节点 membersElement 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);});}
}