1.为什么使用XML
(1) 文件
XML是一项与数据描述和组织有关的技术,因此在学习XML的基本概念之前,我们需要先了解计算机如何存取数据。为此我们把计算机中的数据文件分成两大类:二进制文件和文本文件 。
(2) 二进制文件
二进制文件是由程序根据自己的编码规则创建的,只有创建这个文件的程序才知道如何解析该文件,所以二进制文件有其应用的限制。
比如:我们的doc文件就是word根据自身的编码生成的二进制文件。word的软件设计人员设计了不同内容对应的不同编码,当我么能使用word打开doc文档时,word程序会将二进制编码转换为字符,供我们阅读。
优点 :计算机容易理解、处理速度快、存储效率高。
可以存储不同类型的数据。
缺点 :每一类二进制文件都有自己特有的格式,不能跨程序、跨平台使用。
(3) 文本文件
文本文件实际上也是一个二进制文件,不同的是,文本文件是根据标准的格式组织起来的。
这些标准格式我们习惯称他们为字符集。
常见的字符集 :
ASCII、GB2312、ISO-8859-1、UTF-8 。
由于标准的字符集存在,所以人们可以借助一个文本编辑器就可以轻松的阅读文本文件,
比起二进制文件文本文件更容易分享。
优点 :
易于使用,可以通过不同程序打开。
缺点 :
只能保存纯文本,不能保存其他信息。
(4) 标记语言简史:
文本文件有易用性的特点,但只能存储纯文本,而二进制文件虽然可以存储不同的内容但是通用性较差,如果可以结合二者的优点,岂不快哉?
为达到上述目的,我们想到的方案是为文本文件中不同的内容都加上一个特殊的标记,这样程序就可以根据不同的标记来识别文档中的内容。
这种思想很早就出现了,根据这种思想最早提出的语言是标准通用标准语言(SGML),但是SGML本身比较复杂,并没有得到很好的推广。
在SGML的基础上出现HTML,HTML吸收了很多SGML的概念,它使用html标签来标识网页中的不同部分,这样浏览器就可以通过HTML来显示一个个的WEB页面。
SGML过于复杂,而HTML仅能用来描述网页。不能描述数据,于是XML诞生了。
2.XML简介
(1) 什么是 XML?
XML 指可扩展标记语言(EXtensible Markup Language) 。
XML 是一种标记语言,很类似 HTML 。
XML 的设计宗旨是传输数据,而非显示数据 。
XML 标签没有被预定义。您需要自行定义标签。
XML 被设计为具有自我描述性。
XML 是 W3C 的推荐标准 。
XML 仅仅是纯文本 :
有能力处理纯文本的软件都可以处理 XML。
(2) XML 与 HTML 的主要差异
XML 不是 HTML 的替代。
XML 和 HTML 为不同的目的而设计。
XML 被设计为传输和存储数据,其焦点是数据的内容。
HTML 被设计用来显示数据,其焦点是数据的外观。
HTML 旨在显示信息,而 XML 旨在传输信息。
(3) XML的用途
框架的配置文件 :Sping ;Hibernate。
传输数据 :Ajax ;WebService。
数据的持久化 。
(4) XML的HelloWorld(stu.xml):
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student id="1">
<name>孙悟空</name>
<age>18</age>
<gender>男</gender>
<address>花果山</address>
</student>
<student id="2">
<name>猪八戒</name>
<age>28</age>
<gender>男</gender>
<address>高老庄</address>
</student>
<student id="3">
<name>沙和尚</name>
<age>38</age>
<gender>男</gender>
<address>流沙河</address>
</student>
<student id="4">
<name>唐僧</name>
<age>16</age>
<gender>男</gender>
<address>女儿国</address>
</student>
</students>
(5) 语法规范
①
XML文档的第一行是一个xml声明,用来声明xml的版本和字符集
②XML文档中有且只有一个根元素
③
XML中的标签必须结构完整(成对出现或者是自结束标签)
④
XML中的标签不能交叉嵌套
⑤
XML中的属性必须有值,且值必须加引号
⑥
XML中严格区分大小写
⑦
XML的标签名不能以数字开头
(6) XML解析
XML解析是指通过解析器读取XML文档,解释语法,并将文档转化成对象。
对XML的一切操作都是由解析开始的,所以解析非常重要。
Java 平台同时提供了 DOM(Document Object Model)和 SAX(Simple API for XML)。
(7) 技术体系
(8) DOM解析和SAX解析对比:
3.DOM解析
Document Object Model(文档对象模型):
一次性将整个XML文档全都加载进内存中,生成一棵DOM树,
我们通过对DOM树的操作来解析文档。
(1) 优点:
DOM解析是一种完全面向对象的解析方式,使用起来比较简单
DOM解析一次性将整个文档都加载进内存中,可以反复操作文档,
同时它可以对文档进行增删改查的操作。
(2) 缺点:
一次性将文档都加载进内存中,会占用大量的内存,解析起来性能较差。
(3)
原生DOM解析
核心类:
DocumentBuilderFactory;
DocumentBuilder;
Document
主要步骤:
//1.获取工厂类类实例
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//2.获取解析器类实例
DocumentBuilder builder = factory.newDocumentBuilder();
//3.解析xml文档获取document对象
Document document = builder.parse("stu.xml");
(4) 代码示例:
public class TestDOM {
@Test
public void testDOM() throws Exception{
//获取工厂类实例
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//获取解析器类实例
DocumentBuilder builder = factory.newDocumentBuilder();
//解析xml文档获取document对象
Document document = builder.parse("stu.xml");
//xml文件中所有的标签和属性都是自定义的
//id属性在xml中没有任何意义,所以getElementById暂时不能用
//Element ele = document.getElementById("1");
//System.out.println(ele);
//获取全部的student元素
NodeList stuEles = document.getElementsByTagName("student");
//遍历stuEles
for(int i=0 ; i<stuEles.getLength() ; i++){
//获取student元素
Element stuEle = (Element) stuEles.item(i);
//获取学生的id属性值
String idStr = stuEle.getAttribute("id");
//获取学生name
Element nameEle = (Element) stuEle.getElementsByTagName("name").item(0);
String name = nameEle.getTextContent();
//获取age gender address
String ageStr = stuEle.getElementsByTagName("age").item(0).getTextContent();
String gender = stuEle.getElementsByTagName("gender").item(0).getTextContent();
String address = stuEle.getElementsByTagName("address").item(0).getTextContent();
System.out.println(idStr+"--"+name+"--"+ageStr+"--"+gender+"--"+address);
}
}
}
4.DOM4J 解析
使用dom4j必须要导入一个jar包:
dom4j-1.6.1.jar
dom4j是一个开源XML解析包。
dom4j是一个易用的、开源的库,用于XML,XPath和XSLT。
dom4j内部支持SAX解析,所以性能比原生的DOM要高。
dom4j是基于dom的第三方开源的xml解析jar包。
它应用于Java平台,采用了Java集合框架并完全支持DOM,SAX和JAXP。
(1) dom4j 解析
//创建一个解析器对象
SAXReader reader = new SAXReader();
//解析xml文档来获取document对象
Document document = reader.read("stu.xml");
//DOM4J操作都是通过根元素来进行的,所以我们需要先获取到根元素
Element rootEle = document.getRootElement();
> 常用的方法:
Element getRootElement() 获取根元素
List<Element> elements(String tagName) 根据标签名获取一组元素节点
Element element(String tagName) 根据标签名获取一个元素节点
String attributeValue(String name) 根据属性名获取属性值
String elementText(String tagName) 获取指定的标签中的文本内容
String getText() 获取元素中的文本内容
(2) dom4j 修改
//创建一个漂亮的输出格式
OutputFormat format = OutputFormat.createPrettyPrint();
//创建一个XMLWriter
XMLWriter writer = new XMLWriter(new FileWriter("stu2.xml"),format);
//将document对象写入到文件中
writer.write(document);
//关闭流
writer.close();
> 常用的方法:
Element addElement(Stirng tagName); 向父元素中添加指定的子元素,并返回子元素
Element addAttribute(String name :String value) 向元素中添加属性,并返回当前元素
Element addText(String data) :向元素中添加文本内容,并返回当前元素
DocumentHelper.createDocument():创建一个新的Document
(3) xPath
xPath用来在xml文档中快速查询元素,也就是说快速获取XML文件中的内容;
dom4j支持xPath,使用xPath时需要导入一个新的jar包:jaxen-1.1-beta-6.jar
xPath的具体语法需要对照文档使用。
(4) 代码示例:
public class TestDOM4J {
//xPath用来在xml文档中快速查询元素
@Test
public void testXpath() throws Exception{
//获取解析器类实例
SAXReader reader = new SAXReader();
//解析xml文档获取Document对象
Document document = reader.read("stu.xml");
//查询文档中id为3的学生信息
// /students/student[@id='3']
//selectNodes()可以根据一个xPath表达式查询一组节点
//selectSingleNode()根据一个xPath查询一个节点对象
Element stuEle = (Element) document.selectSingleNode("/students/student[@id='2']");
//获取学生的信息
String idStr = stuEle.attributeValue("id");
String name = stuEle.elementText("name");
System.out.println(idStr+"--"+name);
}
// 修改XML文件(创建新的XML文档)
@Test
public void testDOM4J3() throws Exception{
//创建一个新的Document对象
Document document = DocumentHelper.createDocument();
//向Document中添加一个根元素
Element rootEle = document.addElement("teachers");
//向根元素中添加子元素
rootEle.addElement("teacher").addText("罗老师");
rootEle.addElement("teacher").addText("张老师");
//创建一个XMLWriter
XMLWriter writer = new XMLWriter(new FileWriter("teach.xml"), OutputFormat.createPrettyPrint());
//将Document输出到文档中
writer.write(document);
//关闭流
writer.close();
}
// 修改XML文件(已有XML文档)
@Test
public void testDOM4J2() throws Exception{
//获取解析器类实例
SAXReader reader = new SAXReader();
//解析xml文档获取document对象
Document document = reader.read("stu.xml");
//获取根元素
Element rootEle = document.getRootElement();
//向根元素中添加一个student元素
Element stuEle = rootEle.addElement("student");
//向stuEle中添加一个id属性
stuEle.addAttribute("id", "5");
//向stuEle中添加一个name子元素
Element nameEle = stuEle.addElement("name");
//向name中添加一个文本
nameEle.addText("白骨精");
//添加age gender address
stuEle.addElement("age").addText("18");
stuEle.addElement("gender").addText("女");
stuEle.addElement("address").addText("白骨洞");
//创建一个漂亮的输出格式
OutputFormat format = OutputFormat.createPrettyPrint();
//创建一个XMLWriter
XMLWriter writer = new XMLWriter(new FileWriter("stu2.xml"),format);
//将document对象写入到文件中
writer.write(document);
//关闭流
writer.close();
}
//解析XML文件
@Test
public void testDOM4J() throws Exception {
//创建一个解析器对象
SAXReader reader = new SAXReader();
//解析xml文档来获取document对象
Document document = reader.read("stu.xml");
//DOM4J操作都是通过根元素来进行的,所以我们需要先获取到根元素
Element rootEle = document.getRootElement();
//获取所有的student元素
List<Element> stuEles = rootEle.elements("student");
//遍历stuEles
for (Element stuEle : stuEles) {
//获取id属性值
//attributeValue()作用,可以根据属性名获取属性值
String idStr = stuEle.attributeValue("id");
//获取name值
Element nameEle = stuEle.element("name");
String name = nameEle.getText();
//获取age gender address
String ageStr = stuEle.element("age").getText();
//elementText()可以根据标签名,获取标签中间的内容
String gender = stuEle.elementText("gender");
String address = stuEle.elementText("address");
//将属性封装到student对象中
Student stu = new Student(Integer.parseInt(idStr), name, Integer.parseInt(ageStr), gender, address);
System.out.println(stu);
}
}
}
5.SAX
解析
Simple API for XML:
基于事件回调的机制,一个一个节点的解析,解析完一个在解析下一个。
(1) 优点:
一个节点一个节点的解析,不会占用过多的内存,解析性能好。
(2) 缺点:
基于事件回调的机制,操作起来略复杂。
只能对文档进行查询的操作。
sax解析一旦开始就不能手动停止,必须等到整个文档解析结束。
(3) SAX
解析
核心类:
SAXParserFactory;
SAXParser;
DefaultHandler
//获取工厂类实例
SAXParserFactory factory = SAXParserFactory.newInstance();
//获取解析器类实例
SAXParser parser = factory.newSAXParser();
//解析xml文档
parser.parse("stu.xml", new MyHandler2());
- SAX解析的一切操作都是通过处理器类进行的,一般我们需要去自定一个一个处理器类,这个类需要去继承DefaultHandler。
6.PULL
解析
为了解决SAX解析一旦开始就不能手动停止的问题,出现了PULL解析,PULL解析时Android内置的解析方式。
核心类:XmlPullParserFactory;XmlPullParser
//获取工厂类实例
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
//获取解析器类实例
XmlPullParser parser = factory.newPullParser();
//将被解析的文件设置进解析器
parser.setInput(new FileReader("stu.xml"));