尝试使用ElementTree解析xml文件;由于默认情况下解析器不保留注释,因此使用了http://bugs.python.org/issue8277:
import xml.etree.ElementTree as etree
class CommentedTreeBuilder(etree.TreeBuilder):
"""A TreeBuilder subclass that retains comments."""
def comment(self, data):
self.start(etree.Comment, {})
self.data(data)
self.end(etree.Comment)
parser = etree.XMLParser(target = CommentedTreeBuilder())
以上内容见文件.py。使用进行测试
class TestDocument(unittest.TestCase):
def setUp(self):
filename = os.path.join(sys.path[0], "data", "facilities.xml")
self.doc = etree.parse(filename, parser = documents.parser)
def testClass(self):
print("Class is {0}.".format(self.doc.__class__.__name__))
#commented out tests.
if __name__ == '__main__':
unittest.main()
此barfs带有:
Traceback (most recent call last):
File "/home/goncalo/documents/games/ja2/modding/mods/xml-overhaul/src/scripts/../tests/test_documents.py", line 24, in setUp
self.doc = etree.parse(filename, parser = documents.parser)
File "/usr/lib/python3.3/xml/etree/ElementTree.py", line 1242, in parse
tree.parse(source, parser)
File "/usr/lib/python3.3/xml/etree/ElementTree.py", line 1726, in parse
parser.feed(data)
IndexError: pop from empty stack
我做错了什么?顺便说一下,文件中的xml是有效的(由独立程序检查),并且是utf-8编码的。
备注:
- 使用Python 3.3。在Kubuntu 13.04中,以防万一它是相关的。我确保使用"python3"(而不仅仅是"python")来运行测试脚本
edit:这是使用的示例xml文件;它很小(让我们看看我是否能正确格式化):
<?xml version="1.0" encoding="utf-8"?>
<!-- changes to facilities.xml by G. Rodrigues: ar overhaul.-->
<SECTORFACILITIES>
<!-- Drassen -->
<!-- Small airport -->
<FACILITY>
<SectorGrid>B13</SectorGrid>
<FacilityType>4</FacilityType>
<ubHidden>0</ubHidden>
</FACILITY>
</SECTORFACILITIES>
您添加的示例XML在2.7中对我有效,但在3.3中使用了您描述的堆栈跟踪。
问题似乎出在第一个注释上——在XML声明之后,在第一个元素之前。它不是2.7中树的一部分(但没有引发异常),并导致3.3中的异常。
请参阅Python问题#17901:在包含上述修复程序的Python 3.4中,pop from empty stack
没有出现,而是引发了ParseError: multiple elements on top level
。
这是有道理的:如果你想在树中保留注释,就需要将它们作为节点。XML只允许在文档的顶层有一个节点,因此在第一个"真实"元素之前不能有注释(如果强制解析器保留commments)。
不幸的是,我认为这是您唯一的选择:从XML文件中删除根文档节点之外的注释——要么在原始文件中,要么在解析之前剥离它们。