day07_02_XML解析思想
=============================================================================
XML解析:
解析xml可以做:
1. 如果xml作为配置文件:读取数据。
2. 如果xml作为传输文件:可写可读。
--------------------------------------
xml解析思想:
DOM:将文档加载进内存,形成一颗dom树(document对象),将文档的各个组成部分封装为一些对象。
优点:因为在内存中会形成dom树,可以对dom树进行增删改查。
缺点:dom树非常占内存,解析速度慢。
--------------------------------------
SAX:逐行读取,基于事件驱动(事件调方法)。
优点:不占内存,速度快。
缺点:只能读取,不能回写。
--------------------------------------
DOM4J:是dom4j.org出品的一个开源XML解析包。DOM4J应用于Java平台,采用了Java集合框架并完全支持DOM、SAX和JAXP。
DOM4J 使用起来非常简单。只要你了解基本的XML-DOM模型,就能使用。
Dom:把整个文档作为一个对象。
DOM4J 最大的特色是使用大量的接口。它的主要接口都在org.dom4j里面定义:
Document 定义XML文档
Element 定义XML元素
Text 定义XML文本节点
Attribute 定义XML的属性
Comment 定义XML注释的行为
--------------------------------------
xml常用的解析器:
JAXP:sun公司提供的解析。支持dom和sax。(不好用,sun自己都不用)
JDOM:没火起来。
DOM4J:(dom for java)民间方式,事实证明非常好用,支持dom。
1. 导入jar包dom4j-1.6.1.jar
2. 创建解析器
SAXReader reader = new SAXReader();
3. 解析xml获得document对象
Document document = reader.read(url);
--------------------------------------
示例解析XML(使用xml常用的解析器):
1、得到某个具体的节点内容。例如:第2本书的书名 --> 葵花宝典
2、遍历所有元素节点。
--------------------------------------
XPATH:专门用于查询。
定义了一种规则。
常用的方法:
selectSingleNode()
selectNodes()
使用步骤:
1. 导包jaxen-1.1-beta-6.jar
2. 创建解析器
SAXReader reader = new SAXReader();
3. 解析xml 获得document对象
Document document = reader.read(url);
--------------------------------------
示例解析XML(使用xml的XPATH解析器):
1、得到某个具体的节点内容。例如:第2本书的书名 --> 葵花宝典
2、遍历所有元素节点。
--------------------------------------
XPath:
nodename 选取此节点
/AAA 选择根节点AAA元素
//BBB 选择所有AAA元素,而不考虑它们的位置
//* 全选(忽略深度)
/AAA/BBB[1] 选择AAA的第一个BBB子元素
/AAA/BBB[last[]] 选择AAA的最后一个BBB子元素
.. 选取当前节点的父节点
//@id 选择所有的id属性
//BBB[@id] 选择有id属性的BBB元素
//BBB[not(@*)] 选择没有属性的BBB元素
//BBB[@id='b1'] 选择含有属性id值且其值为'b1'的BBB元素
//*[count(BBB)=2] 选择含有2个BBB子元素的元素
//*[count(*)=2] 选择含有2个子元素的元素
//*[name()='BBB'] 选择所有名称为BBB的元素(这里等价于//BBB)
=============================================================================
<?xml version="1.0" encoding="UTF-8"?>
<书架>
<书 出版社="黑马程序员">
<书名>三国演义</书名>
<作者>罗贯中</作者>
<单价>20</单价>
<批发价>10</批发价>
</书>
<书>
<书名>葵花宝典</书名>
<作者>东方不败</作者>
<单价>15</单价>
</书>
</书架>
示例解析XML(使用xml常用的解析器):
1 package com.itheima.dom4j;
2
3 import java.util.List;
4
5 import org.dom4j.Document;
6 import org.dom4j.DocumentException;
7 import org.dom4j.Element;
8 import org.dom4j.Node;
9 import org.dom4j.io.SAXReader;
10 import org.junit.Test;
11
12 public class TestDom4j {
13 @Test
14 // 1、得到某个具体的节点内容。例如:第2本书的书名 --> 葵花宝典
15 public void test1() throws DocumentException {
16 SAXReader reader = new SAXReader(); // 创建一个xml解析对象
17 Document document = reader.read("src/Book.xml"); // 把xml文档加载到document对象中(即内存中)
18 Element root = document.getRootElement(); // 得到根节点
19 // Element bookNode = root.element("书");
20 // System.out.println(bookNode.getName()); // 书
21 List list = root.elements(); // 得到根节点的所有子节点
22 Element secondBook = (Element) list.get(1); // 得到第二本书对象
23 String name = secondBook.element("书名").getText(); // 得到当前节点的文本内容
24 System.out.println(name);
25 }
26
27 @Test
28 // 2、遍历所有元素节点。
29 public void test2() throws DocumentException {
30 SAXReader reader = new SAXReader(); // 创建一个xml解析对象
31 Document document = reader.read("src/Book.xml"); // 把xml文档加载到document对象中(即内存中)
32 Element root = document.getRootElement(); // 得到根节点
33 treeWalk(root);
34 }
35
36 private void treeWalk(Element ele) {
37 // System.out.println(ele.getName()); // 输出当前节点的名字(第一次递归的当前节点是根节点)
38 for (int i = 0; i < ele.nodeCount(); i++) { // ele.nodeCount() 得到当前节点的所有子节点的数量
39 Node node = ele.node(i); // 取出下标为i的节点
40 if (node instanceof Element) { // 判断当前节点是否为元素类型
41 treeWalk((Element) node); // 是,把断当前节点node类型强转为元素Element
42 } else {
43 System.out.print(node.getText());
44 }
45 }
46 }
47
48 }
示例解析XML(使用xml的XPATH解析器):
1 package com.itheima.dom4j;
2
3 import java.util.List;
4
5 import org.dom4j.Document;
6 import org.dom4j.Node;
7 import org.dom4j.io.SAXReader;
8 import org.junit.Test;
9
10 public class TestXPath {
11 @Test
12 // 1、得到某个具体的节点内容。例如:第2本书的书名 --> 葵花宝典
13 public void test() throws Exception {
14 SAXReader read = new SAXReader();
15 Document document = read.read("src/Book.xml");
16 Node node = document.selectSingleNode("/书架/书[2]/书名"); // 类似于路径
17 System.out.println(node.getText());
18 }
19
20 @Test
21 // 2、遍历所有元素节点。
22 public void test2() throws Exception {
23 SAXReader read = new SAXReader();
24 Document document = read.read("src/Book.xml");
25 List list = document.selectNodes("//*"); // 双反斜杠表示忽略深度的意思。单斜杠表示深度,更具体。
26 for (int i = 0; i < list.size(); i++) {
27 Node node = (Node) list.get(i);
28 System.out.println(node.getName() + " " + node.getText());
29 }
30 }
31 }