对ElementTree解析器进行子类化以保留注释

时间:2013-12-13 19:46:54

标签: python xml

尝试使用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())

以上是在documents.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编码。

说明(S):

  • 使用Python 3.3。在Kubuntu 13.04中,以防它是相关的。我确保使用“python3”(而不仅仅是“python”)来运行测试脚本。

编辑:这是使用的示例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>

1 个答案:

答案 0 :(得分:1)

您添加的示例XML在2.7中适用于我,但在3.3中使用您描述的堆栈跟踪中断。

问题似乎是第一个注释 - 在XML声明之后,在第一个元素之前。它不是2.7中的树的一部分(尽管不会引发异常),并导致3.3中的异常。

请参阅Python issue #17901:在包含上述修补程序的Python 3.4中,pop from empty stack不会发生,但会引发ParseError: multiple elements on top level

哪个有意义:如果要在树中保留注释,则需要将它们作为节点进行处理。 XML只允许文档顶层的一个节点,因此在第一个“真实”元素之前不能有注释(如果强制解析器保留通知)。

所以不幸的是,我认为这是你唯一的选择:从XML文件中删除根文档节点之外的那些注释 - 在原始文件中,或者在解析之前剥离它们。