如何用Python的xml.etree模块获取XML文件中节点的位置?
获取XML节点的行号(基于Python xml.etree)
问题描述
我正在使用Python3中的xml.etree模块解析XML文件,代码示例如下:
Python代码:
# test.py import xml.etree.ElementTree as ET tree = ET.parse('test.xml') root = tree.getroot() node = root[0]
XML文件内容:
<?xml version="1.0.0"?> <root> <node>test</node> </root>
我想要获取test.xml中node节点的位置(至少是行号,比如示例中的第2行),但浏览ElementTree类的方法后未找到相关实现,请问该如何实现此功能?
解决方案
标准库的xml.etree.ElementTree本身不记录节点的行列位置信息,因为它是基于SAX解析的简化实现,默认不会保留这些元数据。要获取节点的位置,你可以通过以下两种方式实现:
方法1:扩展SAX解析器记录行号
自定义SAX处理器,在解析过程中统计换行符、记录每个节点的行号,并把行号附加到对应的Element对象上:
import xml.etree.ElementTree as ET from xml.sax import handler, make_parser class LineNumberingHandler(handler.ContentHandler): def __init__(self): self.element_stack = [] self.root = None self.current_line = 1 def startElement(self, name, attrs): elem = ET.Element(name, attrs) elem._line_number = self.current_line # 给节点附加行号属性 if self.element_stack: self.element_stack[-1].append(elem) else: self.root = elem self.element_stack.append(elem) def endElement(self, name): self.element_stack.pop() def characters(self, content): # 通过内容里的换行符更新当前行号 self.current_line += content.count('\n') def parse_with_line_numbers(xml_path): parser = make_parser() handler = LineNumberingHandler() parser.setContentHandler(handler) parser.parse(xml_path) return handler.root # 使用示例 root = parse_with_line_numbers('test.xml') node = root[0] print(f"node节点的行号:{node._line_number}") # 输出:node节点的行号:2
方法2:使用lxml库(更简便)
如果允许引入第三方库,lxml原生支持节点位置信息,用法更直接:
from lxml import etree tree = etree.parse('test.xml') root = tree.getroot() node = root[0] print(f"node节点的行号:{node.sourceline}") # 输出:node节点的行号:2
注意事项
- 方法1中自定义的
_line_number属性加下划线是为了避免和节点自身的属性冲突; lxml除了sourceline行号属性,还能通过相关方法获取更多文档元数据,功能更全面。
内容的提问来源于stack exchange,提问作者OrthoPole
相关产品推荐
相关产品推荐

