技巧: 轻量级 XML 库

2002-8-19 9:11:26【作者】 畅享网 【进入论坛】
广告

技巧: 轻量级 XML 库 
 
--避免常用 API 的复杂性



David Mertz 博士(
mertz@gnosis.cx
手势学家,Gnosis Software,Inc.
2002 年 3 月

在这篇技巧文章中,David 告诉您何时不使用重量级 XML API。诸如 SAX、DOM 和 XSLT 的标准 XML API 提供了转换和操纵 XML 文档的完善方法。但是其中的每一种都十分复杂,需要几百页规范文档和无数第三方书籍来加以说明和讲解。对于简单任务,有更简单的方法来完成 XML 工作。David 还提供了到许多轻量级 XML 库的链接,以及程序员该什么时候使用它们的指示。

XML 应该是容易的。它的承诺是:在不同平台和编程语言之间提供一种简单、直接和统一的数据交换方式。遗憾的是,用于操纵 XML 的最常见 API 一点也不简单。它们每一个都有几百页规范文档和相当陡峭的学习曲线。实际上,XML 本身也变得比其最初的承诺要复杂一些。应该有一种更容易的方法 — 事实上,的确有许多更简单的方法。

就其内部而言,这篇技巧文章中所指的大多数轻量级 API 被构建为(类)SAX 库的更高级别封装器。要使用高级别 API,程序员无需知道关于底层解析器的很多知识。从各个方面来说,简化的 API 只是为 XML 程序员进行处理提供了某些方便。

有两种使用轻量级 XML 库的一般方法。一种方法将 XML 转换成面向行的格式,人们熟悉的工具,如 wc、tail、head、uniq、grep、sed、awk — 和更复杂的方式,如 perl 和其它脚本语言 — 习惯于处理这种格式。另外一种方法是根据给定编程语言的“本机”数据结构使用表示 XML 文档的库。这种库可用于许多编程语言,它调用起来通常要比调用 DOM、XSLT 或 SAX 更简单(对于给定语言的程序员也更直观)。

面向行的 XML

PYX 格式是 XML 文档面向行的表示。PYX 本身不是 XML,但是它却能够表示 XML 文档内的信息。此外,需要时可以将 PYX 文档本身转换回 XML。在 PYX 中,每行的第一个字符标识该行的内容类型。前缀字符是:

PYX 前缀字符
(  开始标记
)  结束标记
A  属性
-  字符数据
?  处理指令

面向行的文本处理工具和技术的广泛使用和方便以及人们对它的熟悉推动了 PYX。这些工具通常期待新行分隔的记录,并且依靠正则表达式模式来识别文本的部分(奇匹配适合于 PYX 而不是 XML)。

PYX 库存在于几种编程语言,但是大多数时候,仅仅使用命令行工具 xmln(非验证)和 xmlv(验证)最有用。

同 XML 不同,PYX 格式允许您容易地对文档提出大量的特别问题。例如:样本文档中的所有属性值是什么?我们可以使用 PYX 简单地询问:

[PYX]# ./xmln test.xml | grep "^A" | awk '{print $2}'

或者,我们可以试图转储 XML 文档的非空内容行:

[PYX]# ./xmln test.xml | grep '^-[^\n ]' | sed s/^-//

可以使用 SAX 或 DOM 编写定制应用程序来完成上述询问,但是这样的查询的确值得成为一种一揽子解决方案。

本地化

DOM 的 API 方法使您能够访问表示 XML 文档的某个数据结构。问题是这个数据结构一点也不象编程语言内置的数据类型。许多库都向 XML 文档的“本地”版本发展。

Python 的 xml_objectify

当使用我自己的 Python 模块 xml_objectify 来读入 XML 文档时,您所得到的是一个非常简单的 Python 对象,其对象属性对应根文档元素的子元素和属性。子元素和标记属性之间的唯一区别是:它们是包含更多对象还是包含纯文本。测试(Python)属性所含内容的类型就足以确定它是作为子元素还是作为 XML 属性开始的。

请首先记住,您怎样才能使用 DOM 查看 XML 文档中的数据:

对 XML 数据结构的 Python DOM 访问

from xml.dom import minidom

dom = minidom.parse('test.xml')

print'flavor='+dom.childNodes[1].getAttribute('flavor')

print'PCDATA='+dom.childNodes[1].childNodes[5].childNodes[0].nodeValue

相比之下,xml_objectify 让用户以更直观、更 Python 化的方式引用 XML 文档数据:

对 XML 数据结构的 xml_objectify 访问

from xml_objectify import XML_Objectify

py_obj = XML_Objectify('test.xml').make_instance()

print 'flavor=' + py_obj.flavor

print 'PCDATA=' + py_obj.MoreSpam.PCDATA

Ruby 的 REXML

REXML 库是以多模式运行的 Ruby 编程语言使用的库。流解析器以类似于 SAX 的方式工作,但是却有更面向 Ruby 的语法。树模式最有趣。基本上,这种模式十分类似于您使用 xml_objectify 或 Perl 的 XML::Parser“树”风格获取的数据表示。REXML 库的一个优点在于其类似 XPath 的区域指定器语法的集成。例如,REXML 教程显示这些行:

REXML 树模式解析和数据结构 require "rexml/document"

include REXML

doc = Document.new File.new("mydoc.xml")

doc.elements.each("inventory/section")

 { |element| puts element.attributes["name"] }

Java 的 JDOM

Java 也参与本地竞赛。尽管 DOM 本身的样式很象 Java,DOM 对编程语言保持中立的方法仍然不必很复杂(即便在 Java 中)。JDOM 是 XML 处理的更原始的 Java 版本。就让我们看一看 JDOM 任务语句来弄清这点:

没有令人信服的理由使操纵 XML 的 Java API 变得复杂、棘手、不直观或者头痛。JDOM 既是以 Java 为中心也是 Java 的优化。它的行为象 Java,它使用 Java 集合,对于目前的 Java 开发人员,它是完全自然的 API,它为使用 XML 提供了低成本入口点。

Perl 的 TMTOWTDI

在 Perl 编程语言的文化里,程序员们有一句格言:“做事情有不止一种方法。”这句口号很有名,以至于经常将其缩写为 TMTOWTDI。和您所期望的一样,Perl 开发人员提出了许多使用 XML 的不同方法。虽然确实存在支持如 DOM 和 SAX 等标准的 Perl 模块,但大多数 Perl 程序员却更喜欢体现 Perl 的主要优点(懒惰、傲慢及急躁)的模块。Perl 程序员认为,比起遵守严格、复杂的标准,他们可以做得更好、更快并且所需的工作也更少。

为了同其它编程语言的风格一致,树风格的 XML::Grove 和 XML::Parser 都将 XML 文档解析成非常 Perl 化的本地数据结构。

Haskell 的 HaXml

HaXml 本身很象 Haskell。它不一定简单,但是它却极其优雅。HaXml 极好地将函数编程风格带入了 XML 操纵。和讨论过的其它模块一样,HaXml 使 XML 文档看起来很象本地数据结构。

下面的示例快速地演示了如何才能进行到 HTML 的类 XSLT 转换:

输出易经 HTML 表的 HaXml 程序

module Main where
import XmlLib
main = processXmlWith (hexagrams `o` tag "IChing")
hexagrams =
    html [
      hhead [htitle [keep /> tag "title" /> txt] ],
      hbody [htableBorder [rows `o` children `with` tag "hexagram"] ]
    ]
htableBorder = mkElemAttr "TABLE" [("BORDER",("1"!))]
rows f = hrow [hcol [num], hcol [nam], hcol [jdg]] f
         where num = keep /> tag "number" /> txt
               nam = keep /> tag "name" /> txt
               jdg = keep /> tag "judgement" /> txt


 结束语

我建议您尝试这些轻量级库。对于您使用 XML 所做的许多普通工作,使用这些库都能完成得更快,并且更容易熟练掌握。即使您使用我没有讨论过的语言,请检查保存语言库的通常位置 — 那里可能有一些适合您的内容。

参考资料

关于 XML,您的确需要了解的内容在Extensible Markup Language (XML) 1.0 W3C Recommendation里。当然,确切地理解这表示什么需要一点精明。

Pyxie 主页(Python PYX 库以及 xmlv 和 xmln 工具的 C 版本)由 Sourceforge 托管。

称为 XmlConnect 的项目的思想非常象 PYX。这两种格式大部分兼容(它们都从 SGML 的 ESIS 获得灵感)。

可以在 developerWorks 上找到我的描述 xml_objectify 的文章:

XML Matters #2: On the 'Pythonic' treatment of XML documents as objects(II)”(developerWorks 8 月,2000 年)

XML Matters #11: Revisiting xml_pickle and xml_objectify”(developerWorks 6 月,2001 年)

请参阅
Ruby REXML 库主页。

也请参阅
Java JDOM 库主页。

CPAN 托管
XML::Grove 模块的文档

在 CPAN 上还可以找到
XML::Parser 模块的文档

试用新的
IBM WebSphere Studio 开发环境,它可以轻而易举地生成动态电子商务应用程序。

关于作者

David Mertz 使用完全没有结构观念的头脑来撰写结构化文档格式。可以通过
mertz@gnosis.cx 和 David 联系,可以从 http://gnosis.cx/publish/ 了解他的生活。 

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

我们都知道,信息技术是企业经营管理目标的手段之一。通俗点说,信息技术对企业而言就是一个工具。

IT管理—君无心[原创]文档信息安全简谈

文档信息安全工作要根据自身的需求来具体部署,也就是量体裁衣。信息安全等级划分、企业商业机密等是不同的概念。

第二届中国管理软件与IT服务年会—2..

“第二届中国管理软件与IT服务年会”于2008年7月23日-25日举行,由AMT集团与畅享网共同主办,无锡扬名高新技术产业园特别赞助支持。

CIO职场,强者生存?

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