Python 是由 Guido van Rossum 开发的可免费获得的高级解释型语言。其语法简单易懂,而其面向对象的语义功能强大,却又灵活随意。Python 几乎适用于每一种计算机平台,并且在平台间具有很强的可移植性。
XML 是“标准通用标记语言”(SGML) 的一种简化版本。通过一种特殊的文档类型 HTML,您也许非常熟悉 SGML。XML 文档与 HTML 一样,都是由散布于文本中的、以尖括号括起的标记确定其结构的文本组成的。但 XML 包含了许多系统标记,它们使 XML 可以用于多种用途:杂志文章和用户文档、结构化数据的文件(如 CSV 和 EDI 文件)、程序间中间通信的消息、建筑图纸(如 CAD 格式)以及许多其它用途。可以创建一组标记,以生成任何一种您想要表达的结构化信息,这就是为什么 XML 会逐渐流行,成为表示各种信息的公共标准。
有效的 HTML 几乎就是有效的 XML,但又不完全相同。这里有两个主要的差异,XML 标记是区分大小写的,并且所有 XML 标记都需要一个显式的结束符号(作为结束标记,而这对于某些 HTML 标记是可选的;例如: <img src="X.png" /> )。使用 xml.dom 的一个简单示例就是使用 HtmlBuilder() 类将 HTML 转换成 XML。
Python 程序员可以通过将任意 Python 对象导出为 XML 实例来实现相当多的功能和通用性。这就允许我们以习惯的方式来处理 Python 对象,并且可以选择最终是否使用实例属性作为生成 XML 中的标记。只需要几行(从 building.py 示例派生出),我们就可以将 Python“原生”对象转换成 DOM 对象,并对包含对象的那些属性执行递归处理。
函数 object_convert() 有一些限制。例如,不可能用以上的过程生成符合 XML 文档的 quotations.dtd:#PCDATA 文本不能直接放到 quotation 类中,而只能放到类的属性中(如 .text )。一个简单的变通方法就是让 object_convert() 以特殊方式处理一个带有名称的属性,例如 .PCDATA 。可以用各种方法使对 DOM 的转换变得更巧妙,但该方法的妙处在于我们可以从整个 Python 对象开始,以简明的方式将它们转换成 XML 文档。
还应值得注意的是在生成的 XML 文档中,处于同一个级别的元素没有什么明显的顺序关系。例如,在作者的系统中使用特定版本的 Python,源码中定义的第二个 quotation 在输出中却第一个出现。但这种顺序关系在不同的版本和系统之间会改变。Python 对象的属性并不是按固定顺序排列的,因此这种特性就具有意义。对于与数据库系统相关的数据,我们希望它们具有这种特性,但是对于标记为 XML 的文章却显然不希望具有这种特性(除非我们想要更新 William Burroughs 的 "cut-up" 方法)。
DOM 的一大优点是它可以让程序员以非线性方式对 XML 文档进行操作。由相匹配的开/关标记括起的每一块都只是 DOM 树中的一个“节点”。当以类似于列表的方式维护节点以保留顺序信息时,则顺序并没有什么特殊之处,也并非不可改变。我们可以轻易地剪下某个节点,嫁接到 DOM 树的另一个位置(如果 DTD 允许,甚至嫁接到另一层上)。或者添加新的节点、删除现有节点,等等。
"""Manipulate the arrangement of nodes in a DOM object """
from
try_dom3
import
*
#-- Var 'doc' will hold the single <quotations> "trunk" doc = dom_obj.get_childNodes()[0]
#-- Pull off all the nodes into a Python list # (each node is a <quotation> block, or a whitespace text node) nodes = []
while
1:
try
: node = doc.removeChild(doc.get_childNodes()[0])
except
:
break
nodes.append(node)
#-- Reverse the order of the quotations using a list method # (we could also perform more complicated operations on the list: # delete elements, add new ones, sort on complex criteria, etc.) nodes.reverse()
#-- Fill 'doc' back up with our rearranged nodes
for
node
in
nodes:
# if second arg is None, insert is to end of list doc.insertBefore(node, None)