1. XML简介
(1) XML的文档结构
XML(可扩展标记语言,Extensible Markup Language)是一种用于标记电子文档使其具有结构性的标记语言。它通过定义一套规则来编码文档,使其在人和机器之间易于理解。XML文档结构包括以下几部分:
- 声明部分:声明XML的版本和编码格式,例如:
<?xml version="1.0" encoding="UTF-8"?>
- 根元素:每个XML文档必须且只能有一个根元素,其他元素都是根元素的子元素。
- 元素:通过开始和结束标签定义,例如:
<element>content</element>
- 属性:为元素提供附加信息,例如:
<element attribute="value">content</element>
- 内容:位于元素标签之间的文本或其他子元素。
(2) XML应用
XML被广泛应用于数据交换和存储,常见的应用场景包括:
- 配置文件:例如Java的Spring框架的配置文件。
- 数据传输:例如Web服务中的SOAP协议。
- 文档格式:例如微软的Office文档格式(.docx, .xlsx)。
- RSS/Atom:用于新闻聚合和博客订阅。
2. 解析XML概述
解析XML是指读取XML文档并将其内容转换为可操作的数据结构。常见的解析方法包括DOM、SAX和StAX等。
- DOM(Document Object Model):将整个XML文档加载到内存中,构建成树形结构,适合小型文档的处理。
- SAX(Simple API for XML):基于事件驱动的解析方式,不会将整个文档加载到内存中,适合大型文档的处理。
- StAX(Streaming API for XML):基于流的解析方式,结合了DOM和SAX的优点。
3. 使用DOM读取XML数据
(1) DOM概念
DOM(Document Object Model)是一种跨平台的、与语言无关的接口,将XML文档表示为一个树形结构,其中每个节点都是文档的一部分。DOM允许程序在内存中操作文档结构、添加、修改或删除元素和内容。
使用DOM读取手机收藏信息
<PhoneInfo>
<Brand name="华为">
<Type name="P90"/>
<Type name="Mate60"/>
</Brand>
<Brand name="苹果">
<Type name="Iphone X"/>
<Type name="Iphone XR"/>
</Brand>
</PhoneInfo>
java代码:
//解析器工厂实例
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
//从DOM工厂获取DOM解析器
Document doc= null;
try {
DocumentBuilder db= dbf.newDocumentBuilder();
doc = db.parse("XML文件路径");
} catch (ParserConfigurationException e) {
throw new RuntimeException(e);
} catch (SAXException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
//读取
NodeList list=doc.getElementsByTagName("Brand");
//先拿最外面的标签内容
for (int i = 0; i < list.getLength(); i++) {
Node brand=list.item(i);
Element brandEle=(Element) brand;
String brandStr=brandEle.getAttribute("name");
NodeList types=brandEle.getChildNodes();
//再根据最外面的拿里面的标签内容
for (int j = 0; j < types.getLength(); j++) {
Node type=types.item(j);
if(type.getNodeType()==Node.ELEMENT_NODE){
Element typeEle=(Element) type;
String typeStr=typeEle.getAttribute("name");
System.out.println("手机:"+brandStr+typeStr);
}
}
}
4. 使用DOM维护XML数据
使用DOM不仅可以读取XML数据,还可以修改和维护XML数据
//解析器工厂实例
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
//从DOM工厂获取DOM解析器
Document doc= null;
try {
DocumentBuilder db= dbf.newDocumentBuilder();
doc = db.parse("XML文件位置");
} catch (ParserConfigurationException e) {
throw new RuntimeException(e);
} catch (SAXException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
//创建brand节点
Element brandElement= doc.createElement("Brand");
brandElement.setAttribute("name","三星");
//创建Type节点
Element typeElement= doc.createElement("Type");
typeElement.setAttribute("name","NoteX");
//添加父子关系
brandElement.appendChild(typeElement);
Element phoneElement=(Element) doc.getElementsByTagName("PhoneInfo").item(0);
phoneElement.appendChild(brandElement);
//修改NoteX
// 获取Type元素并修改name属性
NodeList typeList = doc.getElementsByTagName("Type");
for (int i = 0; i < typeList.getLength(); i++) {
Element tyElement = (Element) typeList.item(i);
if (tyElement.getAttribute("name").equals("NoteX")) {
tyElement.setAttribute("name", "SAMSUNG");
}
}
// 获取Type元素并删除name属性为SAMSUNG的节点
NodeList list = doc.getElementsByTagName("Type");
for (int i = 0; i < list.getLength(); i++) {
Node typeNode = list.item(i);
if (typeNode.getNodeType() == Node.ELEMENT_NODE) {
Element tElement = (Element) typeNode;
if ("SAMSUNG".equals(tElement.getAttribute("name"))) {
tElement.getParentNode().removeChild(tElement);
}
}
}
try {
//保存XML文件
TransformerFactory transformereFactory=TransformerFactory.newInstance();
Transformer transformer=transformereFactory.newTransformer();
DOMSource domSource=new DOMSource(doc);
//设置编码类型
transformer.setOutputProperty(OutputKeys.ENCODING,"gb2312");
StreamResult result=new StreamResult(new FileOutputStream("XML文件要保存的位置"));
//把DOM树转换成XML文件
transformer.transform(domSource,result);
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (TransformerException e) {
throw new RuntimeException(e);
}
5. 使用DOM4J解析XML
(1) DOM4J API概述
DOM4J是一个用于读、写、操作XML的开源框架,提供了比DOM更高效的API。DOM4J使用SAX解析器来解析XML,并在内存中创建一个树形结构。它支持XPath、XSLT等高级功能,是处理XML的强大工具。
(2) 使用DOM4J操作XML数据
以下是使用DOM4J解析和操作XML数据的示例:
// 解析XML文件
SAXReader reader = new SAXReader();
Document document = null;
try {
document = reader.read(new File("XML文件地址"));
} catch (DocumentException e) {
e.printStackTrace();
}
// 获取根元素
Element root = document.getRootElement();
// 读取Brand节点内容
Iterator<Element> brandIterator = root.elementIterator("Brand");
while (brandIterator.hasNext()) {
Element brand = brandIterator.next();
String brandName = brand.attributeValue("name");
Iterator<Element> typeIterator = brand.elementIterator("Type");
while (typeIterator.hasNext()) {
Element type = typeIterator.next();
String typeName = type.attributeValue("name");
System.out.println("手机:" + brandName + " " + typeName);
}
}
// 创建Brand节点
Element brandElement = root.addElement("Brand");
brandElement.addAttribute("name", "三星");
// 创建Type节点
Element typeElement = brandElement.addElement("Type");
typeElement.addAttribute("name", "NoteX");
// 修改NoteX为SAMSUNG
brandIterator = root.elementIterator("Brand");
while (brandIterator.hasNext()) {
Element brand = brandIterator.next();
Iterator<Element> typeIterator = brand.elementIterator("Type");
while (typeIterator.hasNext()) {
Element type = typeIterator.next();
if ("NoteX".equals(type.attributeValue("name"))) {
type.addAttribute("name", "SAMSUNG");
}
}
}
// 删除name属性为SAMSUNG的Type节点
brandIterator = root.elementIterator("Brand");
while (brandIterator.hasNext()) {
Element brand = brandIterator.next();
Iterator<Element> typeIterator = brand.elementIterator("Type");
while (typeIterator.hasNext()) {
Element type = typeIterator.next();
if ("SAMSUNG".equals(type.attributeValue("name"))) {
brand.remove(type);
}
}
}
// 保存修改后的XML文件
try {
XMLWriter writer = new XMLWriter(new FileOutputStream("XML文件要保存的位置"), OutputFormat.createPrettyPrint());
writer.write(document);
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
通过DOM和DOM4J解析XML,可以方便地读取、修改和维护XML数据。
两者之间的区别/应用场景:DOM适合处理较小的XML文档,而DOM4J则提供了更高效的API和更多的高级功能,适合处理大型XML文档和复杂的XML操作。