1.XML入门

1.1 引入

HTML, 超文本标记语言。

html语言语法是很松散的!

1)标签不区分大小写的!

2)标签可以不匹配的。

由w3c组织,针对html的语法缺陷,去设计了另一门,叫xml语言。

html语言的标签是固定的。

1.2 XML语言

XML:,  Extend Markup lanuage 可扩展标记语言。

HTML               XML

概念       超文本标记语言      可扩展标记语言

标记数量   是固定的             是不固定的,可扩展的

作用       负责网页的结构

1)描述带关系的数据结构(作为软件的配置文件)

配置使用场景:

1)框架(struts2 , hibernate,spring),xml作为框架的配置文件

2)tomcat服务器软件配置文件(web.xml server.xml)

2)装载数据(作为小型的“数据库”)。

1.3组成部分

1. 文档声明
  1. 格式:<?xml 属性列表 ?>
  2. 属性列表:
    * version:版本号,必须的属性
    * encoding:编码方式。告知解析引擎当前文档使用的字符集,默认值:ISO-8859-1
    * standalone:是否独立
      * 取值:
        * yes:不依赖其他文件
        * no:依赖其他文件
2. 指令(了解):结合css的
  * <?xml-stylesheet type="text/css" href="a.css" ?>
3. 标签:标签名称自定义的
  * 规则:
    * 名称可以包含字母、数字以及其他的字符
    * 名称不能以数字或者标点符号开始
    * 名称不能以字母 xml(或者 XML、Xml 等等)开始
    * 名称不能包含空格

2.XML作用

2.1 作为软件配置文件

PCweb服务器:学生管理系统 - > 添加学生 -> name=张三,age=20  -》 提交到后台程序 - 》 把数据存储到数据库中

两台通讯条件;

IP地址和端口

java代码:

根据ip和端口连接数据库服务器(ip改动会改变代码)

properties文件:

ip=211.34.21.43

port=20

xml文件:
<host-list>
<host id="main">
<ip> 211.34.21.43</ip>
<port>20</port>
</host>
<host id="backup">
<ip> 211.34.21.44</ip>
<port>20</port>
</host>
</host-list>

PC数据库服务器1:oracle数据库      211.34.21.43     20

PC数据库服务器2:oracle数据库      211.34.21.44     20

2.2 作为小型数据库

教师管理系统      教师信息: 姓名  工龄  邮箱地址

传输数据:

字符串:  张|三|20|zhangsan@qq.com|.......|....    (格式不是行业规范的,不通用)

xml格式:

         <teacher-list>

                <teacher>

                       <name></name>

                       <email></email>

                       <workage></workage>

                        ....

                </teacher>

                <teacher>

                    <name></name>

                    <email></email>

                    <workage></workage>

                     ....

              </teacher>
<teacher-list> (xml是w3c组织的制定的标准)

财务系统

发邮件给教师:

邮箱地址   姓名

方案1:财务系统中也存储了一套教师信息。数据维护成本比较高了!!!

方案2: 财务系统使用的教师数据从教师管理系统中发送过去的。

3.XML语法

3.1 标签

<student>学生</student>

注意:

1)分带标签体的标签,也有空标签。

2)标签是区分大小写

3)标签一定要配对

4)标签中间不能含有空格

5)不能使用数字开头

6)如果没有指定名称空间的话, 标签名中间不能含有冒号

7)在同一个xml文件中,有且仅有一个根标签

3.2 属性

<student id="1"></student>

注意:

1)一个属性分为属性名和属性值。属性名和值之间使用=号分割。

2)属性值一定要使用单引号或者双引号包含,不能省略,也不能单双混用!

3)一个标签内可以包含多个属性,但是不能出现同名的属性

3.3 注释

<!--  xml --->

3.4 文档声明

<?xml version="1.0"  encoding="码表"?>

version: xml的版本号,必须要写

encoding: 表示解析xml文件内容时使用的码表

xml文件的编码问题:

1)xml文件内容保存的编码(另存为-》选择编码保存)

2)解析xml文件内容的编码(   <?xml version="1.0" encoding="utf-8"?> )

以上两个编码必须保存一致,才能避免中文乱码问题。

注意:

如果在ecplise开发工具上,编写xml文件,那么xml文件内容自动按照文档声明的encoding的编码保存,所以不会中文乱码问题.

3.5 转义字符

和html的转义字符.

3.6 CDATA块

把CDATA块中的内容全部原样输入

3.7 约束

规定xml文档的书写规则
  作为框架的使用者(程序员):
    1. 能够在xml中引入约束文档
    2. 能够简单的读懂约束文档

分类:

1. DTD:一种简单的约束技术
    2. Schema:一种复杂的约束技术

#student.dtd
<!ELEMENT students (student*) >
<!ELEMENT student (name,age,sex)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ELEMENT sex (#PCDATA)>
<!ATTLIST student number ID #REQUIRED>

引入dtd文档到xml文档中
  内部dtd:将约束规则定义在xml文档中
  外部dtd:将约束的规则定义在外部的dtd文件中
    本地:<!DOCTYPE 根标签名 SYSTEM "dtd文件的位置">
    网络:<!DOCTYPE 根标签名 PUBLIC "dtd文件名字" "dtd文件的位置URL">

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE students SYSTEM "student.dtd"> <students>
<student number="itcast_0001">
<name>tom</name>
<age>18</age>
<sex>male</sex>
</student> </students>

Schema:
  引入:
    1.填写xml文档的根元素
    2.引入xsi前缀. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3.引入xsd文件命名空间. xsi:schemaLocation="http://www.itcast.cn/xml student.xsd"
    4.为每一个xsd约束声明一个前缀,作为标识 xmlns="http://www.itcast.cn/xml"

<?xml version="1.0"?>
<xsd:schema xmlns="http://www.itcast.cn/xml"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.itcast.cn/xml" elementFormDefault="qualified">
<xsd:element name="students" type="studentsType"/>
<xsd:complexType name="studentsType">
<xsd:sequence>
<xsd:element name="student" type="studentType" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="studentType">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="age" type="ageType" />
<xsd:element name="sex" type="sexType" />
</xsd:sequence>
<xsd:attribute name="number" type="numberType" use="required"/>
</xsd:complexType>
<xsd:simpleType name="sexType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="male"/>
<xsd:enumeration value="female"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ageType">
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="0"/>
<xsd:maxInclusive value="256"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="numberType">
<xsd:restriction base="xsd:string">
<xsd:pattern value="heima_\d{4}"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
<?xml version="1.0" encoding="UTF-8" ?>
<!--
1.填写xml文档的根元素
2.引入xsi前缀. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3.引入xsd文件命名空间. xsi:schemaLocation="http://www.itcast.cn/xml student.xsd"
4.为每一个xsd约束声明一个前缀,作为标识 xmlns="http://www.itcast.cn/xml" -->
<students xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.itcast.cn/xml"
xsi:schemaLocation="http://www.itcast.cn/xml student.xsd"
>
<student number="heima_0001">
<name>tom</name>
<age>18</age>
<sex>male</sex>
</student> </students>

4.XML解析

4.1xml解析方式

1)DOM解析:将标记语言文档一次性加载进内存,在内存中形成一颗DOM树

  优点:操作方便,可以对文档进行CRUD的所有操作。

  缺点:占内存。

2)SAX解析:逐行读取,基于事件驱动的。  

  优点:不占内存。

  缺点:只能读取,不能写(增删改)。

4.2DOM解析的工具

jaxp:sun公司提供的解析器,支持dom和sax两种思想。

jsoup: jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据。

PULL:Android操作系统内置的解析器,sax方式的。

dom4j工具: 三大框架读取xml文件的程序。(非官方的,第三方的)

dom for java

4.3dom4j工具使用

1)到dom4j的官方下载 。dom4j-1.6.1.zip

2)导入dom4j的支持jar包、

dom4j-1.6.1.jar核心包

4.4使用dom4j读取xml的标签

<?xml version="1.0" encoding="utf-8" ?>
<!--<contact
id = "001"
name="张三"
gender="男"
phone="13411112222"
email="zhangsan@qq.com"
address="广州天河">
</contact>-->
<contact-list>
<contact id="001">
<name>张三</name>
<gender>男</gender>
<phone>13411112222</phone>
<email>zhangsan@qq.com</email>
<address>广州天河</address>
</contact>
<contact id="002">
<name>李四</name>
<gender>女</gender>
<phone>13511112222</phone>
<email>lisi@qq.com</email>
<address>广州越秀</address>
</contact>
<student> </student>
</contact-list>
package cn.jxufe.java.chapter01;

import java.io.File;
import java.util.List; import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader; /**
* 使用dom4j工具读取一个xml文件
*
* @author zhao
*
*/
public class w01demo { /*
* 使用dom4j读取xml的标签
* getRootElement(): 获取根标签
* getName(): 获取标签名称
* element("名称"): 获取第一个指定名称的子标签
* elements("名称"): 获取指定名称的所有的子标签
* elements(): 获取所有子标签
*/
public static void main(String[] args) throws DocumentException {
// TODO Auto-generated method stub
SAXReader reader = new SAXReader();// 2)读取xml文件
Document doc = reader.read(new File("./src/contact.xml"));
System.out.println(doc);
/**
* 读取标签
*/
// 1.1 读取根标签
Element rootElem = doc.getRootElement();
System.out.println(rootElem); // 1.2 获取标签名称
System.out.println(rootElem.getName());
// 1.3 获取第一个子标签(根据指定的名称获取第一个子标签)
Element conElem = rootElem.element("contact");
System.out.println(conElem.getName());
System.out.println(conElem);
System.out.println("==============");
// 1.4 获取所有子标签(根据指定的名称获取所有同名子标签)
List<Element> list = rootElem.elements("contact");
// 遍历List
// 几种方式?
// 1)传统for循环
/*for(int i=0;i<list.size();i++){
list.get(i); //根据角标获取指定对象
}*/ // 2)for-each循环
for (Element e : list) {
System.out.println(e);
} // 3)迭代器
/*Iterator it = list.iterator();
while(it.hasNext()){ //hasNext(): 判断是否有下一个元素
it.next(); //next():取出当前对象
}*/ System.out.println("================"); // 1.4 获取所有子标签(不指定名称)
List<Element> eList = rootElem.elements();
for (Element e : eList) {
System.out.println(e);
}
System.out.println("==========="); } }

4.5使用dom4j获取xml上的属性信息

package cn.jxufe.java.chapter01;

import java.io.File;
import java.util.List; import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader; /**
* 使用dom4j获取xml上的属性信息
*
* @author zhao
*
*/
public class w02demo {
public static void main(String[] args) throws DocumentException {
// 1)创建xml解析器
SAXReader reader = new SAXReader();
Document doc = reader.read(new File("./src/contact.xml")); /**
* 读取属性 注意:获取属性,必须先得到属性所在的标签
*/
Element conElem = doc.getRootElement().element("contact");
// 1.1 在标签上获取属性值(根据属性名称获取对应的属性值) String value = conElem.attributeValue("id");
System.out.println(value); Element conElem2 = (Element) doc.getRootElement().elements().get(1);// 返回的是object,强转
System.out.println(conElem2.attributeValue("id")); // 1.2 根据属性名称获取属性对象
// 拿到标签对象
conElem = doc.getRootElement().element("contact");
// 拿到属性对象
Attribute idAttr = conElem.attribute("id");
// 通过属性对象拿到 属性名
String idName = idAttr.getName();
// 通过属性对象拿到 属性值
String idValue = idAttr.getValue();
System.out.println(idName + "=" + idValue); Element conElem3 = (Element) doc.getRootElement().elements().get(1);
// 拿到属性对象
Attribute idAttr2 = conElem3.attribute("id");
// 通过属性对象拿到 属性名
String idName2 = idAttr2.getName();
// 通过属性对象拿到 属性值
String idValue2 = idAttr2.getValue();
System.out.println(idName2 + "=" + idValue2);
System.out.println("=====================");
// 1.3 获取标签的所有属性对象
conElem = doc.getRootElement().element("contact");
List<Attribute> attrList = conElem.attributes();
for (Attribute attr : attrList) {
System.out.println(attr.getName() + "=" + attr.getValue());
}
}
}

4.6使用dom4j获取xml的文本信息

package cn.jxufe.java.chapter01;

import java.io.File;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader; /**
* 使用dom4j获取xml的文本信息
*
* @author zhao
*
*/
public class w03demo { public static void main(String[] args) throws DocumentException {
// TODO Auto-generated method stub
SAXReader reader = new SAXReader();
Document doc = reader.read(new File("./src/contact.xml")); /**
* 注意: 在xml文件中,空格和换行会作为xml的内容被解析到。 xml中空格和换行和java代码中空格换行不一样。
* java代码中的空格和换行是没意义的,为了代码的格式格式好看而已。
*/
Element con = doc.getRootElement().element("contact");
System.out.println(con.getText()); /**
* 读取文本: 注意: 获取文本,要先获取文本所在的标签对象
*/
// 1.1 拿到所在标签上的文本内容
Element nameElem = doc.getRootElement().element("contact").element("name");
String content = nameElem.getText();
System.out.println(content); // 1.2 通过父标签获取指定子标签的文本内容
Element conElem = doc.getRootElement().element("contact");
content = conElem.elementText("gender");
System.out.println(content);
} }

4.7使用dom4j把xml文件的信息封装成对象

package cn.jxufe.java.chapter01;

import java.io.File;
import java.util.ArrayList;
import java.util.List; import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader; /**
* 使用dom4j把xml文件的信息封装成对象
*
* @author zhao
*
*/
public class w04demo { public static void main(String[] args) throws DocumentException {
// TODO Auto-generated method stub
// 目标: contact.xml信息 -> List集合
// 1)读取xml文件
SAXReader reader = new SAXReader();
Document doc = reader.read(new File("./src/contact.xml")); // 2)创建List对象
List<Contact> list = new ArrayList<Contact>(); // List接口-》 ArrayList/LinkedList/Vector // 3)把xml信息->list对象
// 3.1 读取到所有contact标签
List<Element> conList = doc.getRootElement().elements("contact");
for (Element elem : conList) {
// 3.2 创建Contact对象
Contact con = new Contact(); // 3.3 把contact标签数据放入contact对象中
con.setId(elem.attributeValue("id"));
con.setName(elem.elementText("name"));
con.setGender(elem.elementText("gender"));
con.setPhone(elem.elementText("phone"));
con.setEmail(elem.elementText("email"));
con.setAddress(elem.elementText("address")); // 3.4 把contact对象放入list对象
// 保存数据 list.add(对象)
list.add(con);
} // 4)输出
for (Contact con : list) {
System.out.println(con);
}
} }

4.8写出一个xml文件

package cn.jxufe.java.chapter02;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream; import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter; /*
* 写出一个xml文件
*/
public class T01demo { public static void main(String[] args) throws IOException, DocumentException {
// TODO Auto-generated method stub
/*
* 修改xml信息的步骤
* 1)读取到原来的xml文件(document对象)
* 2)操作document对象,改变xml信息(docuement对象)
* 3)把修改后的document对象写出到xml文件中(覆盖原来的文件)
*/ Document doc = new SAXReader().read(new File("./src/contact.xml"));
/*
* 输出流
* 字符输出流:
* Writer -> FileWriter/BufferedWriter
* 方法:
* write(char c): 写出一个字符
* write(char[] data): 写出多个字符
* write(String str): 写出一个字符串
* 字节输出流
* OutputStream -> FileOutputStream/BufferedOutputStream/ObjectOutputStream
* write(byte) :写出一个字节
* write(byte[] data): 写出多个字节
*/
/**
* 把内存的document对象写出到硬盘的xml文件
*/
// 创建输出流
OutputStream outStream = new FileOutputStream("e:/contact.xml");
// 1)创建输出对象
XMLWriter writer = new XMLWriter(outStream);
// 2)写出数据
writer.write(doc);
} }

4.9写出xml文件的细节

package cn.jxufe.java.chapter02;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream; import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter; /**
* 写出xml文件的细节
*
* @author zhao
*
*/
public class T02demo {
public static void main(String[] args) throws DocumentException, IOException {
Document doc = new SAXReader().read(new File("./src/contact.xml")); // 创建输出流
OutputStream outStream = new FileOutputStream("e:/contact.xml");
// 一、设置输出的格式
OutputFormat format = OutputFormat.createCompactFormat();//紧凑的格式.空格和换行去掉了!!
// 系统上线了使用
// OutputFormat format = OutputFormat.createPrettyPrint();// 漂亮的格式。包含空格和换行。 测试时使用
// 二、 设置输出的编码格式
/*
* 作用: 1)影响了xml的文档声明的encoding编码
* 2)影响了xml内容保存的编码
*/
format.setEncoding("gbk"); // 1)创建输出对象
XMLWriter writer = new XMLWriter(outStream, format);
// 2)写出数据
writer.write(doc);
}
}

4.10对XML进行增删改查

package cn.jxufe.java.chapter02;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream; import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter; public class T03demo {
/*
* 查:
标签: element("name")
elements("name")
elements();
getName() 标签名称
getRootElement(): 根标签
属性: atrributeValue("name") 属性值
atrribute("name") 对象
atrributes() 属性对象列表
getName() : 属性名
getValue() 属性值
文本:
getText(); 当前标签的文本
elementText("name") 子标签的文本 增:
DocumentHelper.createDocument() 文档
addElement("name"); 标签
addAtribute("name","value" ) 属性 改:
setValue() 修改属性值
addAttribute(”同名“) 修改属性值
setText() 修改文本内容 删除:
detach() 标签、属性
getParent().remove(标签/属性) */
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
// add();
// edit();
delete(); } public static void add() throws IOException {
// 1.1 添加空文档
Document document = DocumentHelper.createDocument();
// 1.2 添加标签
Element conListElement = document.addElement("contact-list");
Element conElement = conListElement.addElement("contact");
conElement.addElement("name"); // 1.3 添加属性
conElement.addAttribute("id", "001");
conElement.addAttribute("name", "eric"); // 把文档写出到xml文件中
OutputStream out = new FileOutputStream("e:/contact.xml");
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("utf-8"); XMLWriter writer = new XMLWriter(out, format);
writer.write(document);
} public static void edit() throws DocumentException, IOException {
Document doc = new SAXReader().read(new File("./src/contact.xml"));
// 修改属性
// // 1.1 先得到属性对象,再调用方法修改属性值
// Element conElem = doc.getRootElement().element("contact");
// Attribute idAttr = conElem.attribute("id");
// idAttr.setValue("003"); // 1.2 在标签中添加同名的属性,覆盖属性值
Element conElem = doc.getRootElement().element("contact");
conElem.addAttribute("id", "004"); // 修改文本
Element nameElem = doc.getRootElement().element("contact").element("name");
nameElem.setText("王五"); // 把文档写出到XML中
OutputStream out = new FileOutputStream("e:/contact.xml");
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("utf-8");
XMLWriter writer = new XMLWriter(out, format);
writer.write(doc);
} public static void delete() throws DocumentException, Exception {
Document doc = new SAXReader().read(new File("./src/contact.xml"));
// 1.1 删除标签
Element conElem = doc.getRootElement().element("contact");
conElem.detach(); // 自杀
// conElem.getParent().remove(conElem); // 他杀 // // 1.2 删除属性
Attribute idAttr = doc.getRootElement().element("contact").attribute("id");
idAttr.detach(); // 把文档写出到xml文件中
OutputStream out = new FileOutputStream("e:/contact.xml");
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("utf-8"); XMLWriter writer = new XMLWriter(out, format);
writer.write(doc);
}
}

5.xPath技术

5.1引入

问题:当使用dom4j查询比较深的层次结构的节点(标签,属性,文本),比较麻烦!!!

5.2xPath作用

主要是用于快速获取所需的节点对象。

5.3在dom4j中如何使用xPath技术

1)导入xPath支持jar包 。  jaxen-1.1-beta-6.jar

2)使用xpath方法

  List<Node>  selectNodes("xpath表达式");   查询多个节点对象

  Node       selectSingleNode("xpath表达式");  查询一个节点对象

<?xml version="1.0" encoding="utf-8" ?>
<contact-list>
<contact id="001" font="s">
<name>张三</name>
<gender>男</gender>
<phone>13411112222</phone>
<email>zhangsan@qq.com</email>
<address>广州天河</address>
</contact>
<contact id="002">
<name>李四</name>
<gender>女</gender>
<phone>13511112222</phone>
<email>lisi@qq.com</email>
<address>广州越秀</address>
</contact>
<student>
</student>
</contact-list>
package dom4j_xPath;

import java.io.File;
import java.io.FileOutputStream; import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter; public class Demo1 { public static void main(String[] args) throws Exception {
/*
* 需求:删除id为002的标签
*/
Document doc = new SAXReader().read(new File("d:/contact.xml"));
//1.查询id为002的标签
Element contactElem = (Element) doc.selectSingleNode("//contact[@id='002']"); //2.删除标签
contactElem.detach(); OutputFormat format = OutputFormat.createPrettyPrint();//漂亮的格式,有空格和换行,开发、调试的时候用
FileOutputStream out = new FileOutputStream("d:/contact.xml");
format.setEncoding("utf-8");
XMLWriter writer = new XMLWriter(out, format);
writer.write(doc);
writer.close(); }
}

结果:

<?xml version="1.0" encoding="utf-8"?>

<contact-list>
<contact id="001" font="s">
<name>张三</name>
<gender>男</gender>
<phone>13411112222</phone>
<email>zhangsan@qq.com</email>
<address>广州天河</address>
</contact>
<student></student>
</contact-list>

5.4xPath语法

/      绝对路径      表示从xml的根位置开始或子元素(一个层次结构)

//     相对路径       表示不分任何层次结构的选择元素。

*      通配符         表示匹配所有元素

[]      条件           表示选择什么条件下的元素

@     属性            表示选择属性节点

and     关系          表示条件的与关系(等价于&&)

text()    文本           表示选择文本内容

6.SAX解析

6.1回顾DOM解析

DOM解析原理:一次性把xml文档加载进内存,然后在内存中构建Document树。

  对内存要求比较高。

  缺点: 不适合读取大容量的xml文件,容易导致内存溢出。

SAX解析原理: 加载一点,读取一点,处理一点。对内存要求比较低。

6.2SAX解析工具

SAX解析工具-  Sun公司提供的。内置在jdk中。org.xml.sax.*

核心的API:

  SAXParser类: 用于读取和解析xml文件对象

    parse(File f, DefaultHandler dh)方法: 解析xml文件

      参数一: File:表示 读取的xml文件。

      参数二: DefaultHandler: SAX事件处理程序。使用DefaultHandler的子类

package sax;

import java.io.File;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler; public class Demo1 {
public static void main(String[] args) throws Exception {
//1.创建SAXParser对象
SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); //2.调用parse方法
/*
* 参数一:xml文档
* 参数二:DefaultHandler
*/
parser.parse(new File("./src/contact.xml"), new MyDefaultHandler()); }
} /**
* SAX处理程序
*/
class MyDefaultHandler extends DefaultHandler { /*
* 开始文档时调用
*/
@Override
public void startDocument() throws SAXException {
System.out.println("MyDefaultHandler.startDocument()");
} /**
* 开始标签调用
* @param qName:表示开始标签的签名
* @param attributes:表示开始标签内包含的属性列表
*/
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
System.out.println("MyDefaultHandler.startElement()" + qName);
} /**
* 结束标签调用
*
*/
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
System.out.println("MyDefaultHandler.endElement() " + qName);
} /**
* 读到文本内容的时候调用
* @param ch:表示xml的所有的文本内容
* @param start:表示当前文本内容的开始位置
* @param length:表示当前文本内容的长度
*/
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
String content = new String(ch,start,length);
System.out.println("MyDefaultHandler.characters() "+content);
} /*
* 结束文档时调用
*/
@Override
public void endDocument() throws SAXException {
System.out.println("MyDefaultHandler.endDocument()");
}
}

输出:

MyDefaultHandler.startDocument()
MyDefaultHandler.startElement() contact-list
MyDefaultHandler.characters() MyDefaultHandler.startElement() contact
MyDefaultHandler.characters() MyDefaultHandler.startElement() name
MyDefaultHandler.characters() 张三
MyDefaultHandler.endElement() name
MyDefaultHandler.characters() MyDefaultHandler.startElement() gender
MyDefaultHandler.characters() 男
MyDefaultHandler.endElement() gender
MyDefaultHandler.characters() MyDefaultHandler.startElement() phone
MyDefaultHandler.characters() 13411112222
MyDefaultHandler.endElement() phone
MyDefaultHandler.characters() MyDefaultHandler.startElement() email
MyDefaultHandler.characters() zhangsan@qq.com
MyDefaultHandler.endElement() email
MyDefaultHandler.characters() MyDefaultHandler.startElement() address
MyDefaultHandler.characters() 广州天河
MyDefaultHandler.endElement() address
MyDefaultHandler.characters() MyDefaultHandler.endElement() contact
MyDefaultHandler.characters() MyDefaultHandler.startElement() contact
MyDefaultHandler.characters() MyDefaultHandler.startElement() name
MyDefaultHandler.characters() 李四
MyDefaultHandler.endElement() name
MyDefaultHandler.characters() MyDefaultHandler.startElement() gender
MyDefaultHandler.characters() 女
MyDefaultHandler.endElement() gender
MyDefaultHandler.characters() MyDefaultHandler.startElement() phone
MyDefaultHandler.characters() 13511112222
MyDefaultHandler.endElement() phone
MyDefaultHandler.characters() MyDefaultHandler.startElement() email
MyDefaultHandler.characters() lisi@qq.com
MyDefaultHandler.endElement() email
MyDefaultHandler.characters() MyDefaultHandler.startElement() address
MyDefaultHandler.characters() 广州越秀
MyDefaultHandler.endElement() address
MyDefaultHandler.characters() MyDefaultHandler.endElement() contact
MyDefaultHandler.characters() MyDefaultHandler.startElement() student
MyDefaultHandler.characters() MyDefaultHandler.endElement() student
MyDefaultHandler.characters() MyDefaultHandler.endElement() contact-list
MyDefaultHandler.endDocument()

案例:

package sax;

import java.io.File;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler; import com.sun.org.apache.xerces.internal.xni.QName; /**
* 案例:以文本的原格式读取内容到内存
*/
public class Demo2 {
public static void main(String[] args) throws Exception {
//1.创建SAXParser对象
SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); //2.调用parse方法
/*
* 参数一:xml文档
* 参数二:DefaultHandler
*
*/
MyDefaultHandler2 handler = new MyDefaultHandler2();
parser.parse(new File("./src/contact.xml"), handler);
String content = handler.getContent();
System.out.println(content); }
} /**
* SAX处理程序
*/
class MyDefaultHandler2 extends DefaultHandler {
private StringBuffer sb = new StringBuffer(); public String getContent() {
return sb.toString();
} /**
* 开始标签调用
* @param qName:表示开始标签的签名
* @param attributes:表示开始标签内包含的属性列表
*/
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
sb.append("<" + qName);
//判断是否有属性
if (attributes != null) {
for (int i = 0; i < attributes.getLength(); i++) {
String attrName = attributes.getQName(i);
String attrValue = attributes.getValue(i);
sb.append(" " + attrName + "=\"" + attrValue + "\"");
}
}
sb.append(">");
} /**
* 结束标签调用
*
*/
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
sb.append("</" + qName);
} /**
* 读到文本内容的时候调用
* @param ch:表示xml的所有的文本内容
* @param start:表示当前文本内容的开始位置
* @param length:表示当前文本内容的长度
*/
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
String content = new String(ch, start, length);
sb.append(content);
} }

最新文章

  1. C#:lock锁与订单号(或交易号)的生成
  2. javascript中求浏览器窗口可视区域兼容性写法
  3. JavaScript 闯关记
  4. 小白学习mysql之优化基础(EXPLAIN的连接类型)
  5. 完善DriveInfoEx源代码 获取计算机硬盘序列号
  6. 集成 WeChat SDK - 支付篇
  7. php+mysql将大数据sql文件导入数据库
  8. C# 根据年月获得此月第一天和最后一天,并计算工作日
  9. Objective-C内存管理教程和原理剖析(四)
  10. 关于Python的self指向性
  11. android_线
  12. [leetcode-593-Valid Square]
  13. python--递归(附利用栈和队列模拟递归)
  14. java实现满天星swing&amp;awt
  15. python练习题-day13
  16. LVS负载均衡下session共享的实现方式-持久化连接
  17. poj1062(分区间迪杰斯特拉,内含测试数据,一直wa的同学可以进来看看)
  18. unity游戏热更新总结
  19. 如何在Windows环境搭建Object C开发环境
  20. Springmvc mvc:exclude-mapping不拦截 无效

热门文章

  1. BigDecimal保留两位小数,或指定精确的位数
  2. vue 拖动调整左右两侧div的宽度
  3. Linux下使用 ipset 封大量IP及ipset参数说明
  4. 三十七、python中的logging介绍
  5. debian sftp/ssh
  6. Jmeter学习前的基本了解
  7. 【ABAP系列】SAP MB5B中FI凭证摘要是激活的/结果可能不正确 的错误
  8. 20191105 《Spring5高级编程》笔记-第12章
  9. oracle--单行函数和多行函数
  10. 实验报告一 &amp;第三周课程总结