分类: Python/Ruby
2008-09-12 15:27:58
对于dom对象的writexml()方法,虽然可以控制一些格式上的输出,但结果并不让人满意。比如我想实现:
- test
- test
而不是:
test
test
如果是象下面的输出结果我无法区分原来文本中是否带有空白,而上一种结果则不存在这一问题。好在我在wxPython自带的XML资源编辑器(xred)发现了美化的代码。代码如下:
1 def Indent(dom, node, indent = 0):
2 # Copy child list because it will change soon
3 children = node.childNodes[:]
4 # Main node doesn't need to be indented
5 if indent:
6 text = dom.createTextNode('\n' + '\t' * indent)
7 node.parentNode.insertBefore(text, node)
8 if children:
9 # Append newline after last child, except for text nodes
10 if children[-1].nodeType == node.ELEMENT_NODE:
11 text = dom.createTextNode('\n' + '\t' * indent)
12 node.appendChild(text)
13 # Indent children which are elements
14 for n in children:
15 if n.nodeType == node.ELEMENT_NODE:
16 Indent(dom, n, indent + 1)
参数说明:
dom为dom对象
node为要处理的元素结点
indent指明缩近的层数
函数说明:
Indent是一个递归函数,当一个结点有子元素时进行递归处理。主要是解决子元素的换行和缩近的处理。这里缩近是写死的,每一级缩近使用一个制表符。如果你愿意可以改为你想要的内容。就是把函数中的'\t'换替一下。或干脆写成一个全局变量,或参数以后改起来可能要容易的多。不过在 中,这样的处理足够了,就没有做这些工作。
Indent基本的想法就是递归遍历所有子结点,在所有需要加入回车和缩近的地方插入相应的文本结点。这样再使用writexml()输出时就是缩近好了的。具体程序不再细说,直接用就行了。
但这里要注意的是:
Indent()要修改原dom对象,因此在调用它之前最好先复制一个临时dom对象,使用完毕后再清除这个临时dom对象即可。下面是详细的调用过程:
1 domcopy = dom.cloneNode(True)
2 Indent(domcopy, domcopy.documentElement)
3 f = file(xmlfile, 'wb')
4 writer = codecs.lookup('utf-8')[3](f)
5 domcopy.writexml(writer, encoding = 'utf-8')
6 domcopy.unlink()
1行 克隆一个dom对象
2行 进行缩近处理
3-4行 进行UTF-8编码处理
5行 生成XML文件
6行 清除dom对象的内容
经过这番处理之后,你的XML文档应该好看多了。