You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python ElementTree打印XML中无Name属性标签的行号?

问题描述

给定如下XML文件:

<School Name = "school1">
  <Class Name = "class A">
    <Student Name = "student"/>
    <Student/>
    <!-- -->
  </Class>
</School>

需求是编写Python脚本,打印所有不含"Name"属性的标签所在的行号。

现有尝试的脚本如下:

import xml.etree.ElementTree as ET

def read_root(root):
  for x in root:
    print(x.lineNum)
    read_root(x)

def main():
  fn = "a.xml"
  try:
    tree = ET.parse(fn)
  except ET.ParseError as e:
    print("Parse error:", str(e))
    print("while reading: " + fn)
    exit(1)
  root = tree.getroot()
  read_root(root)

但该脚本无法获取行号,曾看到基于ElementTree继承的实现示例但无法理解,请问此需求是否可行?如何实现?


实现方案

这个需求完全可行。Python标准库的xml.etree.ElementTree默认不会为元素记录行号,但可以通过继承XMLParser类,重写相关方法来给每个元素绑定行号属性,具体实现步骤如下:

  1. 自定义解析器类
    继承ET.XMLParser,在解析元素开始标签时,获取当前行号并赋值给元素对象:
import xml.etree.ElementTree as ET

class LineNumberParser(ET.XMLParser):
    def start(self, tag, attrs):
        # 调用父类方法创建元素实例
        element = super().start(tag, attrs)
        # 通过底层expat解析器获取当前行号,绑定到元素的line_num属性
        element.line_num = self.parser.CurrentLineNumber
        return element
  1. 修改主逻辑使用自定义解析器
    在解析XML文件时指定使用自定义解析器,同时遍历元素时判断是否满足"不含Name属性"的条件:
def read_root(root):
    for elem in root:
        # 判断元素是否无Name属性
        if "Name" not in elem.attrib:
            print(f"标签<{elem.tag}>的行号: {elem.line_num}")
        # 递归遍历子元素
        read_root(elem)

def main():
    fn = "a.xml"
    try:
        # 使用自定义解析器解析XML文件
        tree = ET.parse(fn, parser=LineNumberParser())
    except ET.ParseError as e:
        print(f"解析错误: {str(e)}")
        print(f"读取文件时出错: {fn}")
        exit(1)
    root = tree.getroot()
    # 检查根元素是否符合条件
    if "Name" not in root.attrib:
        print(f"标签<{root.tag}>的行号: {root.line_num}")
    read_root(root)

if __name__ == "__main__":
    main()
  1. 代码说明
  • 自定义解析器通过self.parser.CurrentLineNumber获取当前行号,这个属性是Python底层的expat解析器提供的原生能力。
  • 遍历元素时新增了属性判断逻辑,只输出符合要求的标签行号。
  • 补充了根元素的检查,避免遗漏根节点的情况。

运行上述脚本后,会输出:

标签<Student>的行号: 4

对应XML中无Name属性的<Student/>标签所在行。

内容的提问来源于stack exchange,提问作者Alex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 13:35:28