以文本方式查看主题 - 中文XML论坛 - 专业的XML技术讨论区 (http://bbs.xml.org.cn/index.asp) -- 『 DTD/XML Schema 』 (http://bbs.xml.org.cn/list.asp?boardid=23) ---- XML 问题 #2 (http://bbs.xml.org.cn/dispbbs.asp?boardid=23&rootid=&id=12021) |
-- 作者:anchen0617 -- 发布时间:11/13/2004 2:21:00 PM -- XML 问题 #2 在 David Mertz 新的有关“XML 问题”专栏的第二部分 -- 也是他对在 XML 和 Python 之间创建更加无缝的集成而不断进行探求的一部分 -- 中介绍了 xml_objectify 模块。 David 描述了如何使用 xml_objectify,以及将该“Python 化”模块用于作为对象的 XML 文档使用的好处。
项目介绍 获得兼容的 XML-SIG 更新 在 Python 中,例如 xmllib、xml.sax、pyxie 和 xml.dom 这样的模块和软件包提供了处理 XML 社区中一些公共 XML 文档的方法。您可能熟悉应用于其它编程语言的类似模块和库。实际上,许多模块都基于语言中性的 XML 标准,它们通常实现以 XML 为中心的处理文档和对象的方法。 常规 XML 协议的 Python 实现提供了以不同方法进行编程的灵活性。例如,可以使用如 DOM 这样的可移植标准,这样,使用一种语言的程序员可以方便地对以另一种语言编写的面向 DOM 的代码进行操作。不过, Python 程序员有时可能宁愿以更类似于“正常”Python 的方法进行编码。在许多情况下,XML 概念性框架看起来似乎更接近于 Python,而不是 Python 的一个组成部分。因此,我开发了一系列用于 XML 文档的“Python 化”模块。 向前一步:如何使用 xml_objectify 从 XML 文档创建 Python 对象 from xml_objectify import XML_Objectify
如您所见,从常规 XML 文档创建本机 Python 对象有两个步骤。首先创建一个类似于 DOM 的中间工厂对象(即用于创建其它对象的对象)。然后,从 XML_Objectify 实例中生成一个或多个 Python 对象实例。请注意,应该使用 xml_pickler 来处理特殊的 PyObjects.dtd 格式文档。(请参阅 XML 问题 #1 了解有关 xml_pickle 的信息。) 也可以在同一行上执行这两步。例如: 在一行中创建 XML/Python 对象 py_obj = XML_Objectify('address.xml').make_instance()
当然,在后一种情况中,不保留工厂对象来产生更多本机对象,而且也将清除包含它的完整 DOM 实例的 ._dom 数据成员。 为进行比较,下例显示了使用 Python 创建 DOM 对象有多简单: 从 XML 文档创建 DOM 对象 from xml.dom.utils import FileReader
FileReader().readXml() 需要实际的文件对象,而 XML_Objectify() 可以接受文件对象或者普通文件名。在这两种情况下,创建对象是一个两行的操作。 使用 xml_objectify 模块和 xml.dom 软件包的不同之处在于最后得到的对象类型。Python DOM 对象是真正的 Python 对象,但它的属性和方法与原始 XML 文档的数据和结构对应程度并不象 XML_Objectify 对象那样接近。Python DOM 对象的属性通常嵌套了 .children 列表,这些列表在语义上并没有什么太大的帮助。要访问样本文档中同一个 XML 属性,可以使用 xml_objectify 的第一行,也可以使用 DOM 的以下四行。下面显示了这四行: 使用 [xml.dom] 和 [xml_objectify] Python 对象 print py_obj.person[1].address.city get_childNodes()[3].get_attributes()['city'].value
DOM 树是按严格定序的节点树组织起来的。枚举这些节点并不困难,但要引用其中特定的节点就非常麻烦了。如果有些节点是空白文本和处理指令节点(您几乎不太关心它们),情况就更糟糕了,因此在节点列表中查找子标记多半要反复试验。在上例中,访问本机属性(例如 .children)和 DOM 样式的方法(例如 .get_childNodes())用在不同的 print 语句中。使用这两种方法时,要知道引用了 XML 文档中哪些数据都很不容易。 相反,上例中第一个 print 语句非常好地文档化了自己。唯一需要注意的一个小问题是必须使用 Python 的基于 0 的列表索引。除此以外,这行只说: "Print the city of the address of the second person in the addressbook." ("New York" 是每个语句都要打印的。)为进一步帮助您理解,py_obj.__class__ 就是 "addressbook",与 XML 文档的根元素对应。每个不仅包含简单文本的属性都是特定类的实例;这个特定类是根据定义它的 XML 标记命名的。 如您所见,xml.dom 使用起来通常比较难,它的语法也很模糊。本机 Python 对象使用起来就简单得多。请注意,xml_objectify 在内部广泛利用了 DOM。实际上,每个 XML_Objectify 实例都包含了一个 ._dom 属性,该属性是打开的 XML 文档的 DOM 树。不过,创建的实例 .make_instance 不包含任何 DOM,它是根标记的类类型。 设计注意事项、限制和告诫 使用类行为的技巧 字符标记处理 使用字符级别的标记时,标记的内容是文本数据和这些数据的标记(常常是排版方面的)的混合体,子标记在层次结构上不是父标记中的一部分。例如, misc_info 对象实际上没有 ital 属性。那么,下面的 XML 类型应该如何表示呢? <misc-info>One of the <ital>most</ital> talented
xml_objectify 将一个称为 ._XML 的特殊属性添加到看起来包含标记字符数据的对象/标记。这个属性在标记中包含文字 XML。例如,如果给定的嵌套对象有 ._XML 属性,pyobj_printer() 函数显示这个文字 XML 而不是递归属性。不过,仍然执行标准递归子标记-对象的创建,因此可以知道哪些属性和结构最适当。 本机 Python 对象只包含根文档 在上面的从 XML 文档创建 Python 对象示例中,如果保留原始的 XML_Objectify 对象 (xml_obj),可以访问它的 .processing_instruction 属性,甚至可以访问它的 ._dom 属性来查看本机 Python 对象忽略了什么。 属性类型简化 子标记属性 Python 名称空间限制 xml_objectify 的前景如何? 重新构造 Python 对象中已删除的信息的一个选择是在转换回 XML 时强制 DTD。即使我使用这一做法的,但在如何处理 Python 运行时添加、删除或修改的属性时,问题仍然存在。修改 Python 对象可能导致有些部分不符合原始 XML 文档的 DTD。不过,如果用户有特定需要,我会将这些能力添加到 xml_objectify。
|
W 3 C h i n a ( since 2003 ) 旗 下 站 点 苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》 |
46.875ms |