• 有效使用 SAX InputSource


    转自:http://www.ibm.com/developerworks/cn/xml/tips/x-tipsaxis/index.html

    当您使用 SAX API 时,所有输入都从使用 org.xml.sax.InputSource 类开始。这个类包含在 SAX API 中,并且提供了输入规范(通过类似于文件或 I/O 流的标准 Java 构造),同时还提供一个公用的系统标识。 接着,SAX 在解析时从 InputSource 抽取这些信息,从而能够解析外部实体以及其它特定于文档来源的资源。

    类似地,当您对 SAX 使用封装器(类似于 JAXP API)时,可以调用不同方法。最后,解析使用 SAX InputSource。例如,考虑 清单 1 中所示的代码段,它使用 JAXP 来启动 SAX 解析。


    清单 1. 将 JAXP 用于 SAX 解析

    [java] view plaincopy
     
    1. SAXParserFactory spf = SAXParserFactory.newInstance();  
    2. SAXParser parser = spf.newSAXParser();  
    3. parser.parse(myFile, myHandler);  

    即使输入了 java.io.File 文件,它也会在被转交给底层 SAX 实现之前转换成 SAX InputSource 。之所以发生这个转换,是因为这个 JAXP 代码最终访问 org.xml.sax.XMLReader 类,该类只为启动解析提供 清单 2 中所示的两个特征符。


    清单 2. 用于 XMLReader 的解析入口点

    [java] view plaincopy
     
    1. public void parse(InputSource inputSource);  
    2. public void parse(String systemID);  

    在此基础上,大多数 SAX 解析器实现(如 Apache Xerces)实际上将字符串系统标识转换为 InputSource ,并将它分配给接收 InputSource 的 parse() 版本。无论您如何编码自己的应用程序,SAX 最终都接收 InputSource 来用于解析。但是,并非所有这样处理的方法都同等地好。

    为了避免您代码中出现令人不快的意外,最好直接使用 SAX InputSource 类,而不是让 JAXP 或 SAX 为您处理这个任务。因为实现必须要处理每种可能的情况,所以您常常会看到构造 InputSource 实例的代码,类似于 清单 3 中所示。


    清单 3. 一般的 InputSource 构造方法

    [java] view plaincopy
     
    1. InputSource inputSource = new InputSource();  
    2. // May be a null parameter  
    3. inputSource.setByteStream(inputStream);  
    4. // May be a null parameter  
    5. inputSource.setCharacterStream(reader);  
    6. // May be a null parameter  
    7. inputSource.setSystemId(systemId);  
    8. // May be a null parameter  
    9. inputSource.setPublicId(publicId);  
    10. // Derived parameter  
    11. inputSource.setEncoding(encoding);  

    正如您从注释中看到的,这些方法中的许多被传递了 null 参数。虽然执行这些方法不会花费很多时间,但 XML 解析应用程序中的每一秒都很关键;遗憾的是,这些不执行任何操作的方法浪费了宝贵的时间。通过自行构造InputSource 实例,您可以将这个过程简化为一至两个方法调用,如 清单 4 所示。


    清单 4. 改进 InputSource 构造

    [c-sharp] view plaincopy
     
    1. InputSource inputSource = new InputSource(myInputStream);  
    2. inputSource.setSystemId("http://www.oreilly.com");  
    3. inputSource.setEncoding("UTF-8");  

    我还使用了 setEncoding() 方法来通知 SAX 解析器使用何种编码;在涉及国际化或使用多字节字符集的 XML 应用程序中,这一点很重要。

    但是,这里产生了另一个问题:对于字符编码,用手工设置字符编码的编码与所提供的输入流(通过java.io.InputStream 或 java.io.Reader )所用的编码 不同 ,这种情况很常见。如果这些编码不匹配,就可能发生各种解析问题。要避免这种情况,请始终用 Java InputStream 创建您的 InputSource ,而不要用 Reader 或String 系统标识(这些都是 JAXP API 的可能选项)。当您提供 InputStream 时,SAX 实现将流封装在InputStreamReader 中;然后 SAX 自动从流中检测正确的字符编码。随后,您可以省略 setEncoding() 步骤,再次减少方法调用。结果是应用程序运行更快了,并且字符编码始终正确。

  • 相关阅读:
    EXT性能优化(转载)
    xampp 下配置mail()函数发邮件
    从存储过程中返回结果 (转载)
    HDU1394 Minimum Inversion Number
    HDU4414 Finding crosses
    POJ1328 Radar Installation
    HDU3308 LCIS
    POJ2352 Stars
    POJ2513 Colored Sticks
    HDU4027 Can you answer these queries?
  • 原文地址:https://www.cnblogs.com/handsome1013/p/5124705.html
Copyright © 2020-2023  润新知