XML——流机制解析器

【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)解析器会产生以下调用

    • step1)startElement, 元素名: font
    • step2)startElement, 元素名: name
    • step3)characters, 内容 a
    • step4)endElement, 元素名: name
    • step5)startElement, 元素名:size,属性:units=“pt”
    • step6)characters, 内容 36
    • step7)endElement, 元素名: size
    • step8)endElement, 元素名: font
  • 3.2)处理器必须覆盖以上方法, 让它们执行在解析文件时想要执行的动作;

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();
  • 4.6)我们还处理了另外一个常见的问题: (干货——如果你不需要验证文件, 只需调用factory.setFeature方法
    • XHTML 文件总是以一个包含对 DTD 引用的标签开头, 解析器将加载这个 DTD。 可以理解的是, W3C 肯定不乐意对诸如www.w3.org/TR/xhtml/DTD/xhtml-strict.dtd 这样的文件提供千万亿次的下载。总有一天,他们会完全拒绝提供这些文件, 至今,它们还在并不情愿地提供DTD下载。如果你不需要验证文件只需调用 factory.setFeature(“http://apache.org/xml/features/nonvalidating/load-external-dtd“,false);

相关文章

引言 NOKIA 有句著名的广告语:“科技以人为本”。任何技术都是为了满足人的生产生活需要而产生的。具体...
Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket Reprint it anywhere u want. 文章...
Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket Reprint it anywhere u want. 文章...
http://blog.jobbole.com/79252/ 引言 NOKIA 有句著名的广告语:“科技以人为本”。任何技术都是为了满...
(点击上方公众号,可快速关注) 公众号:smart_android 作者:耿广龙|loonggg 点击“阅读原文”,可查看...
一、xml与xslt 相信所有人对xml都不陌生,其被广泛的应用于数据数据传输、保存与序列化中,是一种极为强...