一、XML概况
概念
可扩展标记语言,标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言。
语法
所有 XML 元素都须有关闭标签
XML 标签对大小写敏感
XML 必须正确地嵌套
XML 文档必须有根元素
XML 的属性值须加引号
实体引用转义符(<<小于>>大于&&和号''单引号""引号)
XML中的注释
在 XML 中,空格会被保留
使用场景
作为一个小型的数据库来保存数据,这相当于数据载体
作为软件的配置文件
XML 文档定义方式
文档类型定义(DTD)XML Schema。
DTD定义了文档的整体结构以及文档的语法,应用广泛并有丰富工具支持。
XML Schema用于定义管理信息等更强大、更丰富的特征。
schema(即.xsd文件,xml schema document)和dtd(即.dtd文件,Document Type Definition)都是对xml文件的进一步约束,就是说某xml文件(如web.xml)引入了某个.xsd或者.dtd之后,就不能随心所欲的使用任何自定义元素了,必须使用.xsd或者.dtd文件中定义的元素,并且类型、个数、顺序也会受到限制 。
二、解析方式
DOM
1.导入相关类
2.创建DocumentBuilder对象
3.从文件或流中创建Document对象
4.提取根元素
5.处理属性&&子节点
SAX
1、创建一个SAXParserFactory对象。
SAXParserFactory factory = SAXParserFactory.newInstance();
2、创建一个SAXParser对象
SAXParser parser = factory.newSAXParser();
通过parse方法加载xml文件。
parser.parse(xml文件名,handler);
此时与DOM的区别是这里需要一个handler,创建一个handler类。
3、handler类需要继承 DefaultHandler。
其中在xml声明时触发startDocument()方法。在遇到开始标签时会触发startElement()方法。
解析节点元素时可用startElement()方法中地attributes.getQName(i)和attributes.getValue(i)来获得属性名和属性值。
可在endElement()方法中的set方法将xml的内容和结构存入Java对象中。
DOM4j
1.引入jar包
2.获取document对象
3.节点操作

三、解析原理
DOM解析原理
xml解析器一次性将整个xml文档加载进内存,然后在内存中构建一棵Document对象树,通过Document对象可以得到树上的节点对象,通过节点对象就可以操作整个xml文档的内容。在读取xml文档之后,会在内存中形成一棵DOM树,xml文件中的标签作为DOM树的节点,并且xml文档的根节点作为DOM树的根节点,所有的标签构成了一棵具有层次的树。节点存在一些信息:如节点名称、节点类型(标签节点、属性节点、文本节点、注释节点)。具体我们在使用时不用Node对象,而是使用其子类的三个对象。下面显示了DOM面向编程过程中常用的对象。
xml文档---------Document对象 代表整个xml文档
节点-------------Node对象(基础类型) 父类
标签节点---------Element对象 子类
属性节点---------Attribute对象 子类
文本节点---------Text对象 子类
使用Document对象,它代表的是一个完整的xml文档,从而使得整个xml文档可以被读进去。

SAX解析原理
对文档进行顺序扫描,当扫描到文档(document)开始与结束,元素开始与结束、文档结束等地方通知事件处理函数,由事件处理函数相应动作然后继续同样的扫描,直至文档结束。


接口:
ContentHandler接口 (主要用到的接口)
ContentHandler是Java类包中一个特殊的SAX接口,位于org.xml.sax包中。该接口封装了一些对事件处理的方法,当XML解析器开始解析XML输入文档时,它会遇到某些特殊的事件,比如文档的开头和结束、元素开头和结束、以及元素中的字符数据等事件。当遇到这些事件时,XML解析器会调用ContentHandler接口中相应的方法来响应该事件。
ContentHandler接口的方法有以下几种:
void startDocument()//文件打开时调用
void endDocument()//当到文档的末尾调用
void startElement(String uri, String localName, String qName, Attributes atts)//当遇到开始标记时调用
void endElement(String uri, String localName, String qName)//当遇到节点结束时调用
void characters(char[ ] ch, int start, int length)//当分析器遇到无法识别为标记或者指令类型字符时调用
DTDHandler接口
DTDHandler用于接收基本的DTD相关事件的通知。 该接口位于org.xml.sax包中。此接口仅包括DTD事件的注释和未解析的实体声明部分。SAX解析器可按任何顺序报告这些事件,而不管声明注释和未解析实体时所采用的顺序;但是,必须在文档处理程序的startDocument()事件之后,在第一个startElement()事件之前报告所有的DTD事件。
DTDHandler接口包括以下两个方法
void startDocumevoid notationDecl(String name, String publicId, String systemId) nt()
void unparsedEntityDecl(String name, String publicId, String systemId, String notationName)
EntityResolver接口
EntityResolver接口是用于解析实体的基本接口。
该接口只有一个方法,如下:
public InputSource resolveEntity(String publicId, String systemId)
publicId : -//SPRING//DTD BEAN//EN
systemId : http://www.springframework.org/dtd/spring-beans.dtd
首先会读取该xml文档上的声明,根据声明去寻找相应的dtd定义,以便对文档的进行验证,默认的寻找规则,(即:通过网络,实现上就是声明DTD的地址URI地址来下载DTD声明),并进行认证,下载的过程是一个漫长的过程,而且当网络不可用时,这里会报错,就是应为相应的dtd没找到。如果SAX应用程序需要实现自定义处理外部实体,则必须实现此接口。
ErrorHandler接口
ErrorHandler接口是SAX错误处理程序的基本接口。
如果SAX应用程序需要实现自定义的错误处理,则它必须实现此接口,然后解析器将通过此接口报告所有的错误和警告。
该接口的方法如下:
void error(SAXParseException exception)
void fatalError(SAXParseException exception)
void warning(SAXParseException exception)
DOM4j解析原理
结合了sax和dom方式的优点,通过sax加载xml,加载过程中使用dom结构保存数据。
四、不同点
1.与DOM比较而言,SAX是一种轻量型的方法。
我们知道,在处理DOM的时候,我们需要读入整个的XML文档,然后在内存中创建DOM树,生成DOM树上的每个Node对象。当文档比较小的时候,这不会造成什么问题,但是一旦文档大起来,处理DOM就会变得相当费时费力。特别是其对于内存的需求,也将是成倍的增长,以至于在某些应用中使用DOM是一件很不划算的事。这时候,一个较好的替代解决方法就是SAX。
2.SAX在概念上与DOM完全不同。
它不同于DOM的文档驱动,它是事件驱动的,它并不需要读入整个文档,而文档的读入过程也就是SAX的解析过程。所谓事件驱动,是指一种基于回调(callback)机制的程序运行方法。
3.在操作上不同
SAX:只能读取,不能修改。不记录上一个、下一个标签。操作相对复杂。
DOM:操作方便,可以解析,可以修改。形成document树,读取方便。