可爱的 Python:DOM 的动态性
2007-03-29 12:02:41 来源:WEB开发网函数 object_convert() 有一些限制。例如,不可能用以上的过程生成符合 XML 文档的 quotations.dtd:#PCDATA 文本不能直接放到 quotation 类中,而只能放到类的属性中(如 .text )。一个简单的变通方法就是让 object_convert() 以特殊方式处理一个带有名称的属性,例如 .PCDATA 。可以用各种方法使对 DOM 的转换变得更巧妙,但该方法的妙处在于我们可以从整个 Python 对象开始,以简明的方式将它们转换成 XML 文档。
还应值得注意的是在生成的 XML 文档中,处于同一个级别的元素没有什么明显的顺序关系。例如,在作者的系统中使用特定版本的 Python,源码中定义的第二个 quotation 在输出中却第一个出现。但这种顺序关系在不同的版本和系统之间会改变。Python 对象的属性并不是按固定顺序排列的,因此这种特性就具有意义。对于与数据库系统相关的数据,我们希望它们具有这种特性,但是对于标记为 XML 的文章却显然不希望具有这种特性(除非我们想要更新 William Burroughs 的 "cut-up" 方法)。
将 XML 文档转换成 Python 对象
从 XML 文档生成 Python 对象就像其逆向过程一样简单。在多数情况下,用 xml.dom 方法就可以了。但在某些情况下,最好使用与处理所有“类属”Python 对象相同的技术来处理从 XML 文档生成的对象。例如,在以下的代码中,函数 pyobj_printer() 也许是已经用来处理任意 Python 对象的函数。
try_dom3.py """Read in a DOM instance, convert it to a Python object
"""
from
xml.dom.utils
import
FileReader
class
PyObject
:
pass
def
pyobj_printer
(py_obj, level=0):
"""Return a "deep" string description of a Python object"""
from
string
import
join, split
import
types
descript =
''
for
membname
in
dir(py_obj):
member = getattr(py_obj,membname)
if
type(member) == types.InstanceType:
descript = descript + (
' '*level) +
'{'+membname+
'}
'
descript = descript + pyobj_printer(member, level+3)
elif
type(member) == types.ListType:
descript = descript + (
' '*level) +
'['+membname+
']
'
for
i
in
range(len(member)):
descript = descript+(
' '*level)+str(i+1)+
': '+
pyobj_printer(member[i],level+3)
else
:
descript = descript + membname+
'='
descript = descript + join(split(str(member)[:50]))+
'...
'
return
descript
def
pyobj_from_dom
(dom_node):
"""Converts a DOM tree to a "native" Python object"""
py_obj = PyObject()
py_obj.PCDATA =
''
for
node
in
dom_node.get_childNodes():
if
node.name ==
'#text':
py_obj.PCDATA = py_obj.PCDATA + node.value
elif
hasattr(py_obj, node.name):
getattr(py_obj, node.name).append(pyobj_from_dom(node))
else
:
setattr(py_obj, node.name, [pyobj_from_dom(node)])
return
py_obj
# Main test
dom_obj = FileReader(
"quotes.xml").document
py_obj = pyobj_from_dom(dom_obj)
if
__name__ ==
"__main__":
print
pyobj_printer(py_obj)
更多精彩
赞助商链接