如何用Python检测XML中Bound的Value与Condition元素差异并打印行号
问题解决:XML中Bound节点下Value与Condition子元素标签不匹配时输出Value行号
问题背景
XML内容如下:
<File> <Sub_Function_1> <Messages> <Setting> <Data> <Label>Setting_1</Label> <Value> <Measure> <Data>Area</Data> <Bound> <Value> <Data>2000</Data> </Value> <Condition> <Data>0</Data> </Condition> </Bound> <Bound> <Value> <Integer>10000</Integer> </Value> <Condition> <Integer>12000</Integer> </Condition> </Bound> </Measure> </Value> </Data> <Data> <Label>Setting_2</Label> <Value> <Measure> <Data>Area_2</Data> <Bound> <Value> <Integer>2000</Integer> </Value> <Condition> <Data>0</Data> </Condition> </Bound> <Bound> <Value> <Integer>10000</Integer> </Value> <Condition> <Data>12000</Data> </Condition> </Bound> </Measure> </Value> </Data> <Data> <Label>Setting_3</Label> <Value> <Measure> <Data>Area_2</Data> <Bound> <Value> <Speed>2000</Speed> </Value> <Condition> <Data>0</Data> </Condition> </Bound> <Bound> <Value> <Distance>10000</Distance> </Value> <Condition> <Data>12000</Data> </Condition> </Bound> </Measure> </Value> </Data> </Setting> </Messages> </Sub_Function_1> </File>
需求说明
当同一个<Bound>节点下的<Value>子元素与<Condition>子元素的直接子标签不同时,打印<Value>元素所在的行号。例如:
- 第12行
<Value>子元素为<Data>,对应<Condition>子元素为<Integer> - 第60行
<Value>子元素为<Speed>,对应<Condition>子元素为<Data>
预期输出:line no. 12, 15, 60
现有问题
编写的Python代码无法输出任何行号:
from lxml import etree doc = etree.parse('C:/Python/Project.xml') for eqs in doc.xpath('//File[.//Measure//*[2]/Value/*[1]]'): for vqs in doc.xpath('//File[.//Measure//*[3]/Value/*[1]]'): if eqs != vqs : for e in eqs: print("Measure", e.sourceline)
解决方案
原代码问题分析
- XPath定位错误:错误选择了
<File>节点作为遍历对象,没有定位到需要检查的<Bound>节点 - 逻辑混乱:嵌套循环比较的是
<File>节点,没有针对<Bound>下的<Value>和<Condition>子元素做标签对比 - 行号获取错误:尝试输出
<Measure>的行号,不符合需求的<Value>行号要求
正确实现代码
from lxml import etree # 解析XML文件,保留行号信息 parser = etree.XMLParser(remove_blank_text=True) doc = etree.parse('C:/Python/Project.xml', parser) # 存储不匹配的Value行号 mismatch_line_numbers = [] # 遍历所有<Bound>节点,这是检查的核心单元 for bound_node in doc.xpath('//Bound'): # 获取Value下第一个直接子元素的标签 value_child_tag = bound_node.xpath('./Value/*')[0].tag # 获取Condition下第一个直接子元素的标签 condition_child_tag = bound_node.xpath('./Condition/*')[0].tag # 对比标签,不匹配则记录Value元素的行号 if value_child_tag != condition_child_tag: value_element = bound_node.xpath('./Value')[0] mismatch_line_numbers.append(str(value_element.sourceline)) # 格式化输出结果 print(f"line no. {', '.join(mismatch_line_numbers)}")
代码关键点说明
- 精准定位节点:用
//Bound直接定位所有需要检查的<Bound>节点 - 标签对比逻辑:分别提取
<Value>和<Condition>下第一个直接子元素的标签进行对比 - 行号获取:通过
value_element.sourceline获取<Value>元素在原文件中的行号 - 结果格式化:收集所有符合条件的行号后,按需求格式输出
内容的提问来源于stack exchange,提问作者Anonymous
相关产品推荐
相关产品推荐

