【0】README
0.1) 本文文字描述转自 core java volume 2 , 旨在理解 XML——流机制解析器 的基础知识 ;
0.2) for detailed StAX,please visit http://www.jb51.cc/article/p-kfuvmywr-vy.html
【1】XML——流机制解析器概述
1)problem+solution
- 1.1)problem: 如果文档很大,并且处理算法简单,可以在运行时解析节点, 而不必看到完整的树型结构, 那么DOM 解析器的执行效率就低下 了;
- 1.2)solution: 在这种case 下, 我们应该使用流机制解析器;(干货——引入流机制解析器的原因)
2)java 提供的流机制解析器: SAX解析器和添加到Java 6 中的更现代化的 StAX 解析器。 SAX解析器使用的是事件回调, 而StAX解析器提供了解析事件的迭代器;(干货——java提供了SAX流机制解析器+StAX 解析器)
【2】使用SAX解析器 (干货——DOM解析器是基于SAX解析器的)
1)SAX解析器在解析XML 输入的组成部分时会报告事件, 但不会以任何方式存储文档,而是由事件处理器建立相应的数据结构; (干货——SAX解析器在解析XML 输入的组成部分时会报告事件,即SAX解析器是基于事件的)
2)在使用SAX 解析器时,需要一个处理器来为不同的解析器事件定义事件动作,ContentHandler接口定义了若干个在解析文档时解析器会调用的回调方法。 下面是最重要的几个:
- 2.1)startElement 和 endElement: 在每当遇到起始或终止标签时调用;
- 2.2)characters :在每当遇到字符数据事件调用;
- 2.3)startDocument 和 endDocument:分别在文档开始和结束时各调用一次;
3)看个荔枝:解析以下片段时,
<font>
<name>a</name>
<size units="pt">36</size>
</font>
3.1)解析器会产生以下调用:
Attention)
- A1) HTML不是合法的XML, 大多数 HTML 页面都与良构的XML差别很大, 以至于示例程序无法解析它们;
- A2)但是,W3C 编写的大部分页面都是用 XHTML编写的, XHTML 是一种 HTML方言,又是良构的XML; (干货——HTML不是合法的XML,而 XHTML 是一种 HTML方言,又是良构的XML)
4)代码分析:
- 4.1)下面是如何得到SAX 解析器的代码: (干货——如何创建SAX解析器)
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
- 4.2)现在可以处理文档了:
InputStream in = new URL(url).openStream();
saxParser.parse(in,handler);
- 4.3)这里的source 可以是一个文件, 一个URL 字符串或者是一个输入流。Handler 属于 DefaultHandler 的一个子类, DefaultHandler 类为以下四个接口定义了空的方法:
DefaultHandler handler = new DefaultHandler()
{
public void startElement(String namespaceURI,String lname,String qname,Attributes attrs)
{
if (lname.equals("a") && attrs != null)
{
for (int i = 0; i < attrs.getLength(); i++)
{
String aname = attrs.getLocalName(i);
if (aname.equals("href")) System.out.println(attrs.getValue(i));
}
}
}
};
- 4.4)startElement 方法有3个描述元素名的参数: 其中 qname 参数以 prefix:localname的形式报告限定名; 如果命名空间处理特性已经打开, 那么 namespaceURI 和 lname 参数描述的就是 命名空间和 本地名(非限定)。
- 4.5)与DOM解析器一样, 命名空间处理特性默认是关闭 的, 可以调用工厂类的 setNamespaceAware 方法来激活命名空间处理特性:
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
SAXParser saxParser = factory.newSAXParser();