专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »Python » xml文档对象:将 XML 文档作为对象的 Python 化 处理 (II) »正文

xml文档对象:将 XML 文档作为对象的 Python 化 处理 (II)

来源: 发布时间:星期四, 2009年1月8日 浏览:18次 评论:0
  在 David Mertz 新有关“XML 问题”专栏第 2部分 --也是他对在 XML 和 Python的间创建更加无缝集成而不断进行探求部分 -- 中介绍了 xml_objecty 模块 David 描述了如何使用 xml_objecty 以及将该“Python 化”模块用于作为对象XML 文档使用好处

  项目介绍

  XML 问题 #1介绍了在 XML 和 Python的间创建更加无缝和自然集成项目 参考资料部分提供了到其它 developerWorks文章链接在这些文章中我讨论了些常规Python 编程技术和其它有关 XML/Python 主题

  获得兼容 XML-SIG 更新

  XML-SIG 发行版在 beta 版本中更改相当频繁这些更改往往影响到 xml_objecty 功能因此可以从 参考资料中下载已知和 xml_objecty 兼容 XML-SIG 版本

  当 XML-SIG 发行版正式发行并且/或者当 XML 软件Software包作为正式 Python发行版部分时当前 xml_objecty 将进行更新以对正式发行版使用有关当前 xml_objecty 详细信息请参阅 参考资料

  在 XML 和 Python 的间存在不对称性所以该项目 --至少在最初时 -- 包含两个单独模块: xml_pickle 和 xml_objecty 前者用于以 XML 表示任意 Python对象后者用于将 XML 文档本机表示为 Python 对象本文主要讨论 xml_objecty

  在 Python 中例如 xmllib 、 xml.sax 、 pyxie 和 xml.dom 这样模块和软件Software包提供了处理 XML社区中些公共 XML文档思路方法您可能熟悉应用于其它编程语言类似模块和库实际上许多模块都基于语言中性XML 标准它们通常实现以 XML 为中心处理文档和对象思路方法

  常规 XML 协议 Python实现提供了以区别思路方法进行编程灵活性例如可以使用如 DOM这样可移植标准这样使用种语言员可以方便地对以另种语言编写面向DOM 代码进行操作不过 Python员有时可能宁愿以更类似于“正常”Python思路方法进行编码在许多情况下XML 概念性框架看起来似乎更接近于Python而不是 Python 个组成部分因此我开发了系列用于 XML文档“Python 化”模块

  向前步:如何使用xml_objecty

  使用 xml_objecty 很简单而且在模块 doc注释中有详细记载让我们快速浏览些样本代码:

  从 XML 文档创建 Python对象     from
     xml_objecty
    
     import
     XML_Objecty
xml_obj = XML_Objecty(
    'address.xml')
py_obj = xml_obj.make_instance
        


  如您所见从常规 XML 文档创建本机 Python对象有两个步骤首先创建个类似于 DOM中间工厂对象(即用于创建其它对象对象)然后从 XML_Objecty 例子中生成个或多个 Python对象例子请注意应该使用 xml_pickler 来处理特殊 PyObjects.dtd 格式文档(请参阅 XML 问题 #1了解有关 xml_pickle 信息)

  也可以在同行上执行这两步例如:

  在行中创建 XML/Python 对象

py_obj = XML_Objecty(
    'address.xml').make_instance
        


  当然在后种情况中不保留工厂对象来产生更多本机对象而且也将清除包含它完整DOM 例子 ._dom 数据成员

  为进行比较下例显示了使用 Python 创建 DOM 对象有多简单:

  从 XML 文档创建 DOM 对象

from xml.dom.utils import FileReader
dom_obj =
FileReader.readXml(open('address.xml'))


  FileReader.readXml 需要实际文件对象而 XML_Objecty 可以接受文件对象或者普通文件名在这两种情况下创建对象是个两行操作

  使用 xml_objecty 模块和 xml.dom 软件Software包区别的处在于最后得到对象类型Python DOM 对象是真正Python 对象但它属性和思路方法和原始 XML文档数据和结构对应程度并不象 XML_Objecty 对象那样接近Python DOM 对象属性通常嵌套了 .children 列表这些列表在语义上并没有什么太大帮助要访问样本文档中同个XML 属性可以使用 xml_objecty 也可以使用DOM 以下 4行下面显示了这 4行:

  使用 [xml.dom] 和 [xml_objecty] Python对象     pr
     py_obj.person[1].address.city
    
     pr
     dom_obj.get_childNodes[1].get_childNodes[3].
get_childNodes[3].get_attributes[
    'city'].value
    
     pr
     dom_obj._node.children[1].children[3].children[3].
   attributes[
    'city'].children[0].value
        


  DOM树是按严格定序节点树组织起来枚举这些节点并不困难但要引用其中特定节点就非常麻烦了如果有些节点是空白文本和处理指令节点(您几乎不太关心它们)情况就更糟糕了因此在节点列表中查找子标记多半要反复试验在上例中访问本机属性(例如 .children )和 DOM 样式思路方法(例如 .get_childNodes )用在区别 pr 语句中使用这两种思路方法时要知道引用了 XML文档中哪些数据都很不容易

  相反上例中第个 pr 语句非常好地文档化了自己需要注意个小问题是必须使用 Python基于 0 列表索引除此以外这行只说: "Pr the city of theaddress of the second person in the addressbook." ("New York"是每个语句都要打印)为进步帮助您理解 py_obj.____ 就是 "addressbook"和 XML文档根元素对应每个不仅包含简单文本属性都是特定类例子;这个特定类是根据定义它XML 标记命名

  如您所见 xml.dom 使用起来通常比较难语法也很模糊本机 Python对象使用起来就简单得多请注意 xml_objecty 在内部广泛利用了 DOM实际上每个 XML_Objecty 例子都包含了个 ._dom 属性该属性是打开 XML 文档DOM 树不过创建例子 .make_instance 不包含任何DOM它是根标记类类型

  设计注意事项、限制和告诫

  代码自测

  使用 xml_objecty 可以利用所有现有常规 pyobj_prer 是个样本常规其中包括 xml_objecty 模块产生 所有Python 对象可读递归表示通过将 XML文档表示为本机 Python 文档可以重用现有、以抽象方式处理 Python对象当然DOM 对象勉强算得上是 Python对象但要对这些对象以有用方式使用常规就比较困难例如DOM 对象属性嵌套了 .children 列表所以使用例如 pyobj_prer 这样常规将不会产生非常有用输出

  使用类行为窍门技巧

  xml_objecty 提供了种非常精妙窍门技巧使用这种窍门技巧只有在没有定义类情况下才动态地为属性值定义类这可以让您定义具有复杂行为和可以放入特定XML 文档内容属性假设类 person 使用各种思路方法(如果需要包括 .__init__ 思路方法)进行了预定义导入到上例中 XML 地址簿中每个 "person"都将具有给予它所有行为包括对放入例子中数据操作思路方法当然如果在对文档运行 XML_Objecty 的前没有进行预定义类就只是用于在实际XML 中定义属性容器

  标记处理

  XML 标记通常是块级别但某些也属于级别依我看自然 Python表示在每种情况下各不相同块级别子标记易于通过父标记属性表示父标记是根据子标记命名子标记属性值是新Python 对象它也是根据子标记命名类型例如 person 从层次上角度上考虑可以具有 address 和 misc-info 使用 Python可以用 person.address 和 person.misc_info 来引用它们

  使用级别标记时标记 内容是文本数据和这些数据标记(常常是排版方面)混合体子标记在层次结构上不是父标记中部分例如 misc_info 对象实际上没有 ital 属性那么下面 XML 类型应该如何表示呢?

<misc-info>One of the <ital>most</ital> talented
actresses on TV.</misc-info>


  xml_objecty 将个称为 ._XML 特殊属性添加到看起来包含标记数据对象/标记这个属性在标记中包含文字XML例如如果给定嵌套对象有 ._XML 属性 pyobj_prer 显示这个文字 XML而不是递归属性不过仍然执行标准递归子标记-对象创建因此可以知道哪些属性和结构最适当

  本机 Python 对象只包含根文档

  许多 XML文档都伴随着标记和数据内容提供处理指令和/或注释不过由 XML_Objecty 对象 .make_instance 思路方法创建本机 Python 对象只包含文档根标记内容而且将忽略 XML注释;只表示标记属性和数据

  在上面 从 XML 文档创建 Python对象举例中如果保留原始 XML_Objecty 对象( xml_obj )可以访问它 .processing_instruction 属性甚至可以访问它 ._dom 属性来查看本机 Python 对象忽略了什么

  属性类型简化

  所有 XML 属性都转换成串类型 Python 对象属性当前Python不表示属性 XML枚举或数字类型在以后版本中可能加入这样能力但这些通常需要DTD而 xml_objecty 不具有 DTD

  子标记属性

  XML 子标记 或者由对象类型 Python属性表示 或者由这种对象列表表示这要取决于是个还是几个相同类型子标记即由包含相同类型多个子标记特定标记决定例如在上面第个 address.xml 举例中个人联系信息可能包括 1个家庭电话而另个人联系信息可能包括 0 个或几个相应地些 contact_info 对象没有 .home_phone 属性些具有包含个 home_phone 对象 .home_phone 属性还有些具有包含许多 home_phone 对象 .home_phone 属性尽管使用 DTD 情况下有可能施加更多法则但我认为Python应用需要这种动态能力



  Python 名称空间限制

  要知道 Python 名称空间比 XML名称空间小因此有时要修改标记或属性 XML名称 xml_objecty 将破折号、冒号和镑值/散列标志转换成下划线该模块不处理任何其它名称空间冲突例如如果XML 文档有标记 <spam-eggs> 、 <spam_eggs> 、 <spam:eggs> 和 <spam#eggs> 那么 xml_objecty 所创建 Python 对象就不能正确表示 XML文档在大多数情况下这不是问题人们不希望得到 XML文档具有这些冲突标记

  xml_objecty前景如何?

  目前还不能将本机 Python 对象转回带有和读取 XML 文档相同结构XML 文档 xml_objecty 故意舍去 XML文档中有关顺序信息来产生更易理解 Python对象所以可能发生问题Python 属性没有任何预先确定顺序但需要XML 标记和属性以特定顺序排列即使不 需要XML标记来以特定顺序出现顺序在语义上还是很重要(请注意在重复公共子标记情况下Python列表维护顺序)为了转换回XML我们需要或者选择任意顺序或者保留本机 Python对象中顺序信息使得它看上去不太象 Python

  重新构造 Python 对象中已删除信息个选择是在转换回 XML时强制 DTD即使我使用这做法但在如何处理 Python运行时添加、删除或修改属性时问题仍然存在修改 Python对象可能导致有些部分不符合原始 XML 文档DTD不过如果用户有特定需要我会将这些能力添加到 xml_objecty



0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: