1. XML简介
XML(EXtensible Markup Language),可扩展标记语言
特点
XML与操作系统、编程语言的开发平台无关
实现不同系统之间的数据交换
作用
数据交互
配置应用程序和网站
2. XML文档结构
<?xml version="1.0" encoding="UTF-8"?> <books> <!--图书信息 --> <book id="bk101"> <author>王珊</author> <title>.NET高级编程</title> <description>包含C#框架和网络编程等</description> </book> <book id="bk102"> <author>李明明</author> <title>XML基础编程</title> <description>包含XML基础概念和基本作用</description> </book> </books>
3. XML标签
XML文档内容由一系列标签元素组成
<元素名 属性名 = “属性值”>元素内容</元素名>
空元素:
<name> </name> <name></name> <name/>
属性值用双引号包裹
一个元素可以有多个属性
属性值中不能直接包含<、“、&(不建议:‘、>)
4. XML编写注意事项
所有XML元素都必须有结束标签
XML标签对大小写敏感
XML必须正确的嵌套
同级标签以缩进对齐
元素名称可以包含字母、数字或其他的字符
元素名称不能以数字或者标点符号开始
元素名称中不能含空格
5. 转义符
XML中的转义符列表

当元素中出现很多特殊字符时,可以使用CDATA节,如:
<description> <![CDATA[讲解了元素<title>以及</title>的使用]]> </description>
6. 解析XML技术

DOM
基于XML文档树结构的解析
适用于多次访问的XML文档
特点:比较消耗资源
SAX
基于事件的解析
适用于大数据量的XML文档
特点:占用资源少,内存消耗小
DOM4J
非常优秀的Java XML API
性能优异、功能强大
开放源代码
7. DTD
DTD即文档类型定义--Document Type Definition
使每个XML文件可以携带一个自身格式的描述
一个DTD文档可能包含如下内容:
元素的定义规则
元素之间的关系规则
属性的定义规则
编写DTD文档
<?xml version="1.0"?> <!DOCTYPE poem [ <!ELEMENT poem (author,title,content) > <!ELEMENT author (#PCDATA)> <!ELEMENT title (#PCDATA)> <!ELEMENT content (#PCDATA)> ]> <poem> <author>王维</author> <title>鹿柴</title> <content>空山不见人,但闻人语声。返景入深林,复照青苔上。 </content> </poem>
8. DOM解析XML
DOM介绍
文档对象模型(Document Object Model)
DOM把XML文档映射成一个倒挂的树

常用接口介绍
DOM解析包:org.w3c.dom
访问DOM树节点
DOM解析XML文件步骤:
创建解析器工厂对象
解析器工厂对象创建解析器对象
解析器对象指定XML文件创建Document对象
以Document对象为起点操作DOM树
phone.xml
<?xml version="1.0" encoding="GB2312"?> <PhoneInfo> <Brand name="华为"> <Type name="P9"/> </Brand> <Brand name="苹果"> <Type name="Iphone6"/> <Type name="Iphone7"/> </Brand> </PhoneInfo>
ParseXmlDemo.java
package com.liqinglin.test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
public class ParseXmlDemo {
//收藏信息,xml对应的Document对象
private Document document;
//获得DOM树,获得Document对象
public void getDom(){
//获得解析器工厂
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
try {
//根据解析器工厂获得解析器
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
//解析器来解析XML文件获得Document对象
document = documentBuilder.parse("phone.xml");
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//获取手机品牌及型号相关信息
public void showInfo(){
//以Document数起点,先拿到所有的Brand节点
NodeList brands = document.getElementsByTagName("Brand");
//遍历brands,从中拿到每一个Brand节点
for (int i = 0; i < brands.getLength(); i++){
Node node = brands.item(i);
Element eleBrand = (Element) node;
String brandName = eleBrand.getAttribute("name");
System.out.println(brandName);
//继续查找,找每个Brands的子节点出来
NodeList types = eleBrand.getChildNodes();
for (int j = 0; j < types.getLength(); j++){
Node typeNode = types.item(j);
//判断该子节点是否是元素节点
if(typeNode.getNodeType() == Node.ELEMENT_NODE){
Element typeEle = (Element) typeNode;
System.out.println("\t" + typeEle.getAttribute("name"));
}
}
}
}
//为XML文件添加元素
public void addEle(){
//(1)创建<Brand>
Element brand = document.createElement("Brand");
//(2)为<Bradn>设置name属性取值为三星
brand.setAttribute("name", "三星");
Element type = document.createElement("Type");
type.setAttribute("name", "NOTE2");
//将Type作为Brand的子元素
brand.appendChild(type);
//将Brand放到PhoneInfo中去
document.getElementsByTagName("PhoneInfo").item(0).appendChild(brand);
}
//保存XML文件(需要借助转换器 源:最新的dom树 --> 目的地:phone.xml,借助的输出流)
public void saveXML(){
//转换器工厂
TransformerFactory factory = TransformerFactory.newInstance();
//设置缩进
factory.setAttribute("indent-number", 4);
try {
//获取转换器
Transformer transformer = factory.newTransformer();
//指定转换格式
transformer.setOutputProperty(OutputKeys.ENCODING, "GB2312");
transformer.setOutputProperty(OutputKeys.INDENT, "YES");
DOMSource source = new DOMSource(document);
OutputStream out = new FileOutputStream("phone.xml");
StreamResult result = new StreamResult(new OutputStreamWriter(out, "GB2312"));
transformer.transform(source, result);
} catch (TransformerConfigurationException | FileNotFoundException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
//修改元素
public void updateEle(){
//获取所有的Brand
NodeList brands = document.getElementsByTagName("Brand");
for(int i = 0; i < brands.getLength(); i++){
Node brand = brands.item(i);
Element brandEle = (Element) brand;
brandEle.setAttribute("id", i+"");
}
this.saveXML();
}
//删除 华为手机
public void deleteEle(){
//获取所有的Brand
NodeList brands = document.getElementsByTagName("Brand");
for(int i = 0; i < brands.getLength(); i++){
Node brand = brands.item(i);
Element brandEle = (Element) brand;
if(brandEle.getAttribute("name").equals("华为")){
brandEle.getParentNode().removeChild(brandEle);
}
}
this.saveXML();
}
public static void main(String[] args) {
ParseXmlDemo parseXmlDemo = new ParseXmlDemo();
parseXmlDemo.getDom();
parseXmlDemo.addEle();
parseXmlDemo.showInfo();
parseXmlDemo.updateEle();
parseXmlDemo.deleteEle();
parseXmlDemo.saveXML();
}
}9. DOM4J
Document:定义XML文档
Element:定义XML元素
Text:定义XML文本节点
Attribute:定义了XML 的属性
……
Dom4jDemo.java
package com.liqinglin.test;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import java.io.*;
import java.util.Iterator;
public class Dom4jDemo {
private Document document;
//获得document对象
public void loadDocument(){
SAXReader saxReader = new SAXReader();
try {
document = saxReader.read(new File("phone.xml"));
} catch (DocumentException e) {
e.printStackTrace();
}
}
//显示手机的品牌及型号
public void showInfo(){
//获取XML根节点
Element root = document.getRootElement();
//获取所有的<Brand>
Iterator eleBrands = root.elementIterator();
while(eleBrands.hasNext()){
Element brand = (Element) eleBrands.next();
System.out.println(brand.attributeValue("name"));
//获取所有的<Type>
Iterator eleTypes = brand.elementIterator();
while(eleTypes.hasNext()){
Element type = (Element) eleTypes.next();
System.out.println("\t" + type.attributeValue("name"));
}
}
}
//增加新的手机信息
public void addNewPhone(){
//获取XML根元素
Element root = document.getRootElement();
//创建<Brand>
Element eleBrand = root.addElement("Brand");
eleBrand.addAttribute("name", "三星");
//创建<Type>
Element eleType = eleBrand.addElement("Type");
eleType.addAttribute("name", "SX123");
}
//修改节点
public void updatePhone(){
Element root = document.getRootElement();
Iterator eleBrands = root.elementIterator();
int id = 0;
while(eleBrands.hasNext()){
Element brand = (Element) eleBrands.next();
id++;
brand.addAttribute("id", id+"");
}
this.saveXML();
}
//删除节点
public void deletePhone(){
Element root = document.getRootElement();
Iterator eleBrands = root.elementIterator();
while(eleBrands.hasNext()){
Element brand = (Element) eleBrands.next();
if(brand.attributeValue("name").equals("华为")){
brand.getParent().remove(brand);
}
}
this.saveXML();
}
//修改xml文件
public void saveXML(){
OutputFormat format = OutputFormat.createPrettyPrint();
//format.setEncoding("GB2312");
XMLWriter writer = null;
try {
writer = new XMLWriter(new OutputStreamWriter(new FileOutputStream("phone.xml")), format);
writer.write(document);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Dom4jDemo dom4jDemo = new Dom4jDemo();
dom4jDemo.loadDocument();
dom4jDemo.addNewPhone();
dom4jDemo.updatePhone();
dom4jDemo.deletePhone();
dom4jDemo.saveXML();
dom4jDemo.showInfo();
}
}