XML语法及解析XML文档
一 什么是XML?
XML是一种可扩展标记语言, 被设计用来传输和存储数据。
特性:
- 是一门独立的标记语言.
- 具有平台无关性.
- 具有自我描述性.
用途:
1. 网络数据的传输.
2. 数据存储.
3. 配置文件.
二 XML 语法格式
XML文档通常存储在.xml文件中.
语法结构:
1. 文档声明
<?xml version="1.0" encoding="UTF-8"?>
2. 标记 (元素 / 标签 / 节点)
XML文档,由一个个的标记组成.
语法:
开始标记:<标记名称>
结束标记:</标记名称>
标记名称: 标记名称是自定义的 , 命名规则参考Java 的标识符命名规则.
标记内容: 开始标记 与 结束标记之间 是标记的内容部分.
例如:
描述一个姓名:
<name>张三</name>
3. 标记之间可以嵌套 , 但是不允许交叉.
正例:
<person>
<name>张飞</name>
<age>18</age>
</person>
反例:
<person>
<name><age>张飞</name>
18</age>
</person>
4. 一个XML文档, 必须有 且 仅允许存在一个 根标记.
正例:
<persons>
<person>
<name>刘备</name>
<age>18</age>
</person>
<person>
<name>关羽</name>
<age>18</age>
</person>
</persons>
反例:
<person></person>
<person></person>
5. 标记的嵌套关系( 子标记 , 父标记 , 兄弟标记 , 后代标记 , 祖先标记 )
例如 :
<persons>
<person>
<name>小泽马老师</name>
<age>18</age>
</person>
<person>
<name>小泽马老师</name>
<age>18</age>
</person>
</persons>
在上述的案例中:
name是person的子标记
person是name的父标记
name和age是兄弟标记
name是persons和person的后代标记
persons 是name 的祖先标记
6. 标记名称允许重复.
7. 标记的属性.
标记中存在属性, 在开始标记位置, 编写属性列表.
格式:
属性由属性名和属性值组成.
属性名与属性值之间使用等号连接, 属性值使用引号引住.
多个属性之间 ,使用空白符隔开.
例如:
<person id="1001" sex="不详">
<name>武藤马老师</name>
</person>
8. 注释:
注释开始: <!--
注释结束: -->
下面我们看一个案例:
描述一组学生, 存储到一个students.xml文件中
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student id="1001">
<name>张三</name>
<age>18</age>
</student>
<student id="1002">
<name>李四</name>
<age>19</age>
</student>
<student id="1003">
<name>王五</name>
<age>20</age>
</student>
</students>
三 Java解析XML文档
Java中有几种XML解析方式 ? 分别是什么 ? 有什么优缺点 ?
答:
可以回答两种 或 四种:
1. SAX解析
是事件驱动机制的解析方式.
采用逐行读取的方式解析XML , 每当读取到一个标记的开始/结束/内容时 触发程序员事先准备好的处理代码. 进行处理.
优点:
在读取大文件时, 节省内存.
缺点:
1. 因为逐行解析, 当解析第N行时 , 第n-1行的数据 已经被释放了.
2. 因为事件驱动机制, 无法告知程序员节点层次.
3. sax解析是只读解析方式, 无法修改文档内容.
2. DOM解析
直接将整个文档, 加载到内存. 在内存中建立文档树模型 (树对象)
通过操作文档树, 来完成数据的修改 获取 和删除.
优点:
文档一次性加载到内存, 可以进行任意的读取, 修改, 删除.
缺点:
文档一次性加载到内存, 浪费大量的内存.
如果文件较大, 可能无法解析.
3. JDOM解析
是DOM解析的扩展, 与DOM解析的优缺点基本一致;
4. DOM4J解析
是DOM解析的扩展, 与DOM解析的优缺点基本一致;
四 DOM4J解析XML
步骤:
1. 引入jar文件 (dom4j.jar)
2. 创建一个输入流 , 指向一个XML文件.
FileInputStream fis = new FileInputStream("文件的地址");
3. 创建一个XML读取工具对象
SAXReader sr = new SAXReader();
4. 通过读取工具对象, 读取XML文档输入流.并得到返回值( 返回的是读取到的文档对象 )
Document doc = sr.read(fis);
5. 通过文档对象, 获取XML文档中的根元素对象
Element root = doc.getRootElement();
元素对象 Element的常用方法.
以下为常用的方法:
- 获取节点名称
String name = element.getName(); - 获取节点内容
String text = element.getText(); - 设置节点内容
element.setText(String text); - 根据子节点名称, 获取匹配名称的第一个子节点
Element e = element.element(“节点名称”); - 获取所有的子节点对象
List list = element.elements(); - 获取节点属性值
String value = element.attributeValue(String 属性名); - 获取子节点内容
String text = element.elementText(String 节点名称); - 添加子节点
Element e = element.addElement(String 子节点名称); - 添加属性
element.addAttribute(String 属性名,String 属性值);
五 XML文档的生成
步骤:
1. 通过文档帮助器(DocumentHelper) 创建空的文档对象
Document doc = DocumentHelper.createDocument();
2. 通过文档对象, 添加根节点
Element root = doc.addElement("根节点名称");
3. 通过根节点, 丰富文档内容
4. 创建一个文件输出流 , 用于存储XML文件.
FileOutputStream fos = new FileOutputStream("要存储的文件路径");
5. 将文件输出流, 转换为XML文件输出流.
XMLWriter xw = new XMLWriter(fos);
6. 将文档输出到文件中
xw.write(doc);
7. 释放资源
xw.close();