有没有办法从ElementTree元素获取行号

Joh*_*ith 16 python xml elementtree python-3.x

所以我使用Python 3.2.1的cElementTree解析一些XML文件,在解析过程中我发现有些标签缺少属性信息.我想知道是否有任何简单的方法来获取xml文件中这些元素的行号.

Mic*_*son 14

看看文档,我认为没有办法用cElementTree做到这一点.

但是我对lxml的XML实现版本有好运.使用libxml2它应该几乎是替代品.元素有一个sourceline属性.(以及获得许多其他XML功能).

唯一需要注意的是我只在python 2.x中使用它 - 不确定它是如何/如果它在3.x下工作 - 但可能值得一看.

附录:从他们的头版他们说:

lxml XML工具包是C库libxml2和libxslt的Pythonic绑定.它的独特之处在于它将这些库的速度和XML特性完整性与本机Python API的简单性相结合,大多数兼容但优于众所周知的ElementTree API.最新版本适用于2.3到3.2的所有CPython版本.有关lxml项目的背景和目标的更多信息,请参阅简介.常见问题解答中回答了一些常见问题.

所以看起来python 3.x还可以.


Dun*_*ris 10

花了一段时间让我弄清楚如何使用Python 3.x(在这里使用3.3.2)这样做,所以我想总结一下:

# Force python XML parser not faster C accelerators
# because we can't hook the C implementation
sys.modules['_elementtree'] = None
import xml.etree.ElementTree as ET

class LineNumberingParser(ET.XMLParser):
    def _start_list(self, *args, **kwargs):
        # Here we assume the default XML parser which is expat
        # and copy its element position attributes into output Elements
        element = super(self.__class__, self)._start_list(*args, **kwargs)
        element._start_line_number = self.parser.CurrentLineNumber
        element._start_column_number = self.parser.CurrentColumnNumber
        element._start_byte_index = self.parser.CurrentByteIndex
        return element

    def _end(self, *args, **kwargs):
        element = super(self.__class__, self)._end(*args, **kwargs)
        element._end_line_number = self.parser.CurrentLineNumber
        element._end_column_number = self.parser.CurrentColumnNumber
        element._end_byte_index = self.parser.CurrentByteIndex
        return element

tree = ET.parse(filename, parser=LineNumberingParser())
Run Code Online (Sandbox Code Playgroud)

  • @ 7yl4r我设法让它在Python 3.6上运行.关键是在你的程序中的任何地方第一次导入`xml.etree.ElementTree`之前添加这一行:`sys.modules ['_ elementtree'] = None`.例如,您可以在脚本的开头添加`sys.modules ['_ elementtree'] = None`.然后在调用`tree = ET.parse(filename,parser = LineNumberingParser())`之后,`tree.getroot()._ start_line_number`将起作用. (3认同)
  • 有人可以添加一行显示`_start_line_number`属性的用法吗?我正在尝试`tree.getroot()._ start_line_number`并获得`AttributeError`. (2认同)
  • 在 Python 3 中,函数 `_start_list` 应该是 `_start`,无论是在定义 (`def _start(self, *args, **kwargs):`) 和调用中 (`element = super(self.__class__, self )._start(*args, **kwargs) `)。 (2认同)