技巧

使用 DOM 进行自举的基础知识,第 2 部分

改进 DOM 级别 1 和 2 自举

Comments

系列内容:

此内容是该系列 # 部分中的第 # 部分: 技巧

敬请期待该系列的后续内容。

此内容是该系列的一部分:技巧

敬请期待该系列的后续内容。

前一篇技巧文章 中,我解释了 DOM 自举的基础知识,并特别解释了使用 DOM 级别 1 或 2 时这些基础知识将如何付诸实现。您学会了如何获取 DOMImplementation 类的供应商实现,以及如何用它来生成 DocumentDocumentType 对象。而且,最为重要的是,您了解了 DOM 提供的自举功能带来的各种问题。

作为一个简短的温习,在讨论这些问题的解决方案之前,我将概述这些问题:

  1. 产生了对特定解析器的依赖性
  2. 在许多情况下,产生了对特定解析器的特定 版本的依赖性
  3. 对 DOM 实现或解析器的更改需要进行代码级更改和重编译
  4. 对 DOM 实现的更改需要更改 CLASSPATH

在以上各个问题中,只有一个问题在生产环境中是确实可接受的 ― 也就是最后一个问题, 4,对应用程序的 CLASSPATH 的更改。其它三个限制都非常严重,它们会对您能否获得可重用的(有时是可重新销售的)应用程序造成影响。

如果您回忆以下,您就会想起前一篇技巧文章是以清单 1 中所显示的代码片段作为结束的。

清单 1. XMLReader 的解析入口点
DOMImplementation domImpl =
    new org.apache.xerces.dom.DOMImplementationImpl();
DocumentType docType = 
    domImpl.createDocumentType("rootElementName", "public ID", "system ID");
Document doc = domImpl.createDocument("", "rootElementName", docType);

虽然这并不是一个差劲的自举解决方案,但它也并不特别优秀。我们不使用这种方法,也不接受它的限制,让我们来看一种更好的解决方案。在理想情况下,您需要能够从自举过程中除去所有特定于供应商的代码,并在应用程序外指定那个信息。

在理想情况下,您可以在代码中或在应用程序启动时设置系统特性(通过 java 过程的 -D 标志);我更愿意用 org.w3c.dom.DOMImplementationClass 作为该特性的名称。该特性的值是一个实现类,代码需要这一实现类来实例化 DOMImplementation 实例。在示例中,我一直使用 Apache Xerces,因此该特性的值为 org.apache.xerces.dom.DOMImplementationImpl

一旦您适当地掌握了这一基本思想,那么编写一个助手类就相当简单了,该助手类负责读入并实例化上述特性,然后将新对象返回给使 DOM 实例启动和运行所需的代码。清单 2 显示了这样一个助手类。

清单 2. 样本助手类
package com.ibm.xml;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.DOMImplementation;
public class DOMFactory {
    /** System property name */
    private static final String IMPL_PROPERTY_NAME =
        "org.w3c.dom.DOMImplementationClass";
    /** Initialization flag */
    private static boolean initialized = false;
    /** The DOMImplementation to use */
    private static DOMImplementation domImpl;
    private static void initialize() throws Exception {
        domImpl = 
            (DOMImplementation)Class.forName(
                System.getProperty(IMPL_PROPERTY_NAME)).newInstance();
        initialized = true;
    }
    public static Document newDocument(String namespaceURI, String rootQName,
                                       DocumentType docType) 
        throws Exception {
        
        if (!initialized) {
            initialize();
        }
        return domImpl.createDocument(namespaceURI, rootQName, docType); 
    }
    public static DocumentType newDocumentType(String rootQName,
                                               String publicId, String systemId)
        throws Exception {
    
        if (!initialized) {
            initialize();
        }
        return domImpl.createDocumentType(rootQName, publicId, systemId);
    }
}

上面的类实际上非常简单。该类的入口点是两个 public 方法,它们各返回两个 DOM 启动 类中的一个。这两个类是 DOMImplementation 生成的相同的两个类,因此这为您使用助手类提供了一些一致性。这两种方法都确保进行了初始化,然后生成所请求的对象。

初始化也并非那么复杂。系统特性返回一个类名(假定类名使用正确!),然后通过 Class.forName().newInstance() 机制实例化该类名。一旦上述处理完成,那么存储对象以及用它来生成对象就很容易了。

现在您得到了一种更好的自举方法!这一方法真得很简单。在您开始解析之前,只需将这个类连同所需的任何解析器 JAR 文件一起添加到您的类路径中,并且设置系统特性。甚至不用深究特定于供应商的代码,您就可以获得 DOM 类型。在 DOM 级别 3 公开发行以及更好的自举方法出现之前,它将一直助您克服困难,以顺利完成各种任务。还想了解其它知识吗?好!在下一篇技巧文章中,我将详细讨论如何设置 DOM 级别 3 以使之工作,并在自举方法的进展方面给你一个惊喜。到时候网上见!


相关主题

  • 您可以参阅本文在 developerWorks 全球站点上的 英文原文.
  • 本系列有关对 DOM 进行自举的技巧文章的 第1 部分解释了何为自举,探讨了与之相关的一些问题,还介绍了在 DOM 级别 1 和 2 中使用自举的基础知识( developerWorks,2002 年 11 月)。 第 3 部分解释了 DOM 级别 3 中有关自举的一些更改,以及对 DOM 级别 1 和 2 所做的改进( developerWorks,2002 年 12 月)。
  • 请在 W3C.org 上阅读 DOM API
  • 关注 IBM XML 新闻组 NewbiesJava Tools
  • 在 developerWorks XML 专区上查找更多 XML 参考资料。
  • 了解一下 IBM WebSphere Studio Application Developer,它是一个易于使用的集成开发环境,用于构建、测试和部署 J2EE 应用程序,包括从 DTD 和模式生成 XML 文档。
  • 了解如何成为一名 XML 及其相关技术的 IBM 认证开发人员
  • 需要我们每周为您发送与此类似的有用的 XML 技巧文章吗?请注册以订阅 developerWorks XML 技巧时事通讯

评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=XML
ArticleID=21230
ArticleTitle=技巧: 使用 DOM 进行自举的基础知识,第 2 部分
publish-date=12012002