Python ElementTree:实现漂亮打印时出错

0 投票
2 回答
1792 浏览
提问于 2025-04-16 17:51

我有一些用Python的ElementTree库写的XML代码,它生成的XML文件看起来很乱。我想让这个XML文件更易读一些。但是,ElementTree没有提供美化打印的功能。在文档中,ElementTree显示了一个'indent'方法。当我尝试使用这个indent方法时,出现了以下错误。

   Traceback (most recent call last):
      File "/cygdrive/c/data/path/myFile.py", line 756, in <module>
          main()
          ...
          self.writeXML()
          File "/cygdrive/c/data/path/myFile.py", line 248, in writeXML
                self.indent(root)
     File "/cygdrive/c/data/path/myFile.py", line 252, in indent

        i = "\n" + level*"  "
        TypeError: object cannot be interpreted as an index


 def writeXML(self):
   root = self.myTree.getroot()
   self.indent(root)
   self.myTree.write(self.myXML)

 def indent(elem, level=0):
     i = "\n" + level*"  "   #Error Here!!
     if len(elem):
         if not elem.text or not elem.text.strip():
             elem.text = i + "  "
         if not elem.tail or not elem.tail.strip():
             elem.tail = i
         for elem in elem:
             indent(elem, level+1)
         if not elem.tail or not elem.tail.strip():
             elem.tail = i
     else:
         if level and (not elem.tail or not elem.tail.strip()):
             elem.tail = i

我是不是用错了indent方法?还是说这段代码有问题?有没有什么更简单的美化打印的方法推荐?

背景:我以前用过PyXML,它有美化打印的功能。但当我升级到Python 2.6时,PyXML就不再支持了。lxml有美化打印的功能,但在我的系统上无法安装。所以我把所有代码都改成使用ElementTree,因为我知道它能正常工作,并且有我需要的大部分基本功能。

2 个回答

1

因为你把这个放在了一个类里面

    def indent(elem, level=0):
        i = "\n" + level*"  "   #Error Here!!

我本来以为 elem 是这个类的实例(记住通常我们在这里放的是 self)
而 level 实际上是你想传入的 elem

这意味着尝试用一个字符串去乘一个元素会引发 TypeError 错误,我觉得这是合理的。

正如 John Machin 所说,把这段代码从类里拿出来,单独作为一个函数,你应该会更顺利一些

1

你说

i = "\n" + level*"  "
TypeError: object cannot be interpreted as an index

但是那句话里没有任何东西看起来像是索引操作。建议:在不改变你代码的其他部分的情况下,插入

print repr(elem), repr(level)

在上面的语句之前,并且编辑你的问题来展示结果。还要说明你使用的Python版本,以及你是如何导入ElementTree(或cElementTree)的。

你似乎是从effbot的ElementLib复制粘贴了一段代码……除了那句让人困惑但不致命的for elem in elem,其他看起来还不错。

一个主要的问题是,出于某种奇怪的原因,你把它做成了你类里的一个方法,而不是一个独立的函数。你可以选择(1)把它从你的类里拿出来,然后像这样调用它

indent(root)

或者(2)把它的定义改成

def indent(self, elem, level=0)

看看问题是否解决。

更新 问题会解决:

[Python 2.6.6]
>>> import xml.etree.ElementTree as et
>>> et.Element('atag') * "   "
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: object cannot be interpreted as an index

上面那个神秘的错误信息一定是个bug;Python 2.7.1会产生更合理的

TypeError: can't multiply sequence by non-int of type 'Element'

来自同样的代码。

撰写回答