XML——流机制解析器

【0】README

0.1) 本文文字描述转自 core java volume 2 , 旨在理解 XML——流机制解析器 的基础知识 ;
0.2) for detailed StAX, please visit http://blog.csdn.net/pacosonswjtu/article/details/50569728


【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);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值