技巧:使用基于拉的DOM-- 在容易和高效的编程之间找到平衡点

2002-8-19 14:06:28【作者】 畅享网 【进入论坛】
广告

技巧:使用基于拉的DOM

-- 
在容易和高效的编程之间找到平衡点

Uche Ogbuji(uche.ogbuji@fourthought.com

首席顾问,Fourthought,Inc.

2002 年 5 月

XML 应用程序开发人员经常必须应付 SAX 的复杂性或 DOM 的低效率。这篇技巧文章展示了 DOM 的拉方法是如何通过提供简单、高效的解析来高效地跨过这两者之间的鸿沟。

用于将 XML 解析绑定到需要它的应用程序的两个最常见系统是 W3C 的文档对象模型(Document Object Model (DOM))和开放社区的标准 — 用于 XML 的简单 API(Simple API for XML (SAX))。DOM 是一种允许代码直接指向 XML 文档各部分特性的 API,因此易于编程。然而,DOM 通常要求将表示文档每个部分的对象都放入内存中。因为这些对象占用内存的总合可能会多达文档本身所占用内存的 10 倍(或更多),因此 DOM 在处理大文档时的效率很低。SAX 逐位遍历文档树并发送出与当前节点相应的事件。这意味着 SAX 可以抛弃暂时不在范围中的文档部分,这使得它更高效。DOM 是一种允许代码直接读和修改 XML 文档各部分特性的 API,因此易于编程。

为了赋予开发人员 DOM 的容易和 SAX 的效率,有许多项目着重于各种仅在请求 XML 文档某部分时才将其装入的 DOM。这些 API 称为拉 DOM(pull DOM)。

解析还是不解析……

我将提供一个 Python 语言标准库中的示例。我认为,即使您不熟悉 Python,也很容易理解这个示例。Python 的最新版本捆绑了几个 XML 工具,包括一个小的 DOM 实现 minidom 和一个 SAX 库。Python 还提供了一个 pull DOM(在 xml.dom.pulldom 模块中),我将演示这个pull DOM。清单 1 演示了使用 Python 的pull DOM 装入莎士比亚的“哈姆雷特”的著名 Jon Bosak XML 表示法的用法。任务是打印该剧的第 IV 幕第 II 场的第一行。

清单 1:打印“哈姆雷特”第 IV 幕第 II 场的第一行

       1 #Get the first line in Act IV, scene II
     2 
     3 from xml.dom import pulldom
     4 
     5 hamlet_file = open("hamlet.xml")
     6 
     7 events = pulldom.parse(hamlet_file)
     8 act_counter = 0
     9 for (event, node) in events:
    10     if event == pulldom.START_ELEMENT:
    11         if node.tagName == "ACT":
    12             act_counter += 1
    13             scene_counter = 1
    14         if node.tagName == "SCENE":
    15             if act_counter == 4 and scene_counter == 2:
    16                 events.expandNode(node)
    17                 #Traditional DOM processing starts here
    18                 #Get all descendant elements named "LINE"
    19                 line_nodes = node.getElementsByTagName("LINE")
    20                 #Print the text data of the text node
    21                 #of the first LINE element
    22                 print line_nodes[0].firstChild.data
    23             scene_counter += 1

首先,描述一下 hamlet.xml 的大概结构。顶级元素是 PLAY,它包含了许多 ACT 元素和其它元素,ACT 元素又包含了许多 SCENE 元素。SCENE 包含 SPEECH,而 SPEECH 又包含一组 LINE,每个 LINE 由一个演员来讲。这是一个相当简单的层次结构。

在第 3 行中导入库以后,我在第 5 行中打开了 XML 文件并对其解析进行了初始化。pulldom 解析返回一个对象,该对象表示来自该文件的所有解析事件的虚集合。在 9-23 行中,我在这个集合上进行了循环。循环中的每次迭代取回一个事件和一个虚节点,它潜在地表示以该虚节点为根的整个子树。您可以检查它是什么类型的事件 — 含蓄地说,是什么类型的节点 — 以及该节点表面的一些东西,如节点名称。如果您想要关于其子节点的信息,可以等待适当的后续事件或使用 expandNode 方法将该节点展开成其完整的实际 DOM 树。

在第 10 行,我检查当前事件是否元素的开始,这是我在该程序的拉部分关心的唯一事件类型。如果它是 ACT 元素(在第 11 行检查),则我更新此类元素的计数器(在第 8 行初始化),并使 SCENE 元素计数器复位。如果它是 SCENE 元素(在第 14 行检查),则我检查它是否我想要的幕和场号,如果不是,则更新计数器。

如果是我想要的那一幕,则我将如上面所提到的那样,用 expandNode 将该幕的整个 DOM 结构拉到内存中。从此时开始,该节点是常规 DOM 节点,您可以在节点上调用常规 DOM 方法。在第 19 行中,我使用 getElementsByTagName DOM 方法来获得所有名为 LINE 的子孙元素。理解这一点很重要:如果我在第 16 行之前调用了该方法,它将导致一个错误;这是因为,在展开节点之前,没有真正的 DOM 树。理解这一点也很重要:您选择在哪个节点上进行展开决定了产生的效率。如果我选择了展开整个 ACT 而不是 SCENE,则所有其它 SCENE 也都被装进内存。

最后,在抓取了第一个 LINE 元素之后,我在第 22 行中搜寻其文本子节点,并打印其内容。任务完成。

用您熟悉的语言就可以使用拉 DOM

这是一个使用 Python 的示例,但越来越多的语言开始拥有某种类型的拉 API。Perl 有 XML::Twig,遗憾的是,它不是基于 DOM 的,Java 社区正在标准化一个自己的拉 DOM API。拉 DOM 介于 SAX 和 DOM 之间,可以容易地处理任意大小的 XML 文档,不用费太多力气。 

参考资料

Java 社区过程正试图标准化 Java 的拉 API;The Streaming API for XML(StAX),in JSR 173 Streaming API for XML

XML::Twig 是用于基于拉处理的 Perl 模块,但它不是基于 DOM 的。

这里当然有 Python 的 pulldom 模块,本文中用的就是它。

这里是由 Jon Bosak 用 XML 标记的莎士比亚戏剧全集目录(包括“哈姆雷特”)。

IBM WebSphere Studio Site Developer 是一种易于使用的、集成的开发环境,用于构建、测试和部署 Java Server Pages、servlet 和 XML 相关的应用程序以及网站。

看看您如何才能成为 XML 和相关技术的 IBM 认证开发人员(Certified Developer)

想要我们每周都给您发送象这样有用的 XML 技巧文章吗?从这里订阅 developerWorks XML 技巧文章时事通讯。

developerWorks XML 专区上有更多的 XML 参考资料。

关于作者

Uche Ogbuji 是 Fourthought Inc. 的顾问兼共同创始人,该公司是专为企业知识管理提供 XML 解决方案的软件供应商和咨询公司。Fourthought 开发了 4Suite,一个用于 XML、RDF 和知识管理应用程序的开放源码平台。Ogbuji 先生是一位出生于尼日利亚的计算机工程师和作家,他现在美国科罗拉多州博耳德(Boulder)生活和工作。可以通过 uche.ogbuji@fourthought.com 与 Ogbuji 先生联系。

如果您希望与本文章的作者或其所在机构,进一步交流,请联系:畅享网 姜小姐
jill.jiang@amt.com.cn | 021-51096826-112 | 在线联系
企业信息化杂谈[原创]空降CIO的变与不变

CIO需要尽快适应新公司的权力分配体系。在两家公司可能职位名称是一样的,但是对这个职位的责权利可能是很大的不同。

ITSM-适境而为ITIL从操作向服务转移 提高整体..

ITIL第三版的重点从操作转向IT服务,这使得ITIL更加实用,而且有助于提高IT的整体商业价值。

CIO职场,强者生存?

在2008年,我们将继续看到CIO向商业运营方向发展。与此同时,我们也会看到商业管理人员将与技术管理人员一起竞争CIO岗位。 IT领导者的就职机会虽有不少,但其难度将会大幅提高。2……

防震减灾,IT当关

今天,任何的防震救灾体系,都离不开IT技术。地震观测台是数字化的,震害防御需要对以往的地震信息进行数据分析,应急救援要需要现代多样化的通讯技术。如果说,在许多行业,信息技术还只是一……