使用ElementTree提取inter标签name属性并按规则拼接组名
问题解决:提取XML中inter标签的目标值
需求说明
- 提取XML里
<inter>标签的name属性值 - 当该
<inter>下符合run="jbs"且kind="obopay"的<work>标签带有groups属性时,把每个组名和name拼接成name-组名的格式 - 若没有
groups属性,直接保留name
输入XML
<abtshop> <dDirectory>dub</dDirectory> <S>statusd</S> <work>worklogs</work> <custs> <cust>nim-us</cust> </custs> <mileage>999</mileage> <defaults> <default type="mercley"> <user>dairy</user> <exec>slm.sh</exec> <env> <var name="SAN_HOME">youyou-11</var> </env> </default> </defaults> <inters> <inter name="nim_turk" first-day="20230301" historical="20220103" market="multi"> <works> <work kind="obopay" run="jbs"> <args> <arg name="distance">180000</arg> </args> </work> <work kind="silkb" run="jbs"> <args> <arg name="distance">180000</arg> </args> </work> </works> </inter> <inter name="nim_us_m" first-day="20230301" historical="20220103" market="lone"> <works> <work kind="obopay" run="jbs" groups="groupA,groupB"> <args> <arg name="distance">120000</arg> <arg name="jbsopt">xmas_size=1200000</arg> <arg name="jbsopt">of_obopaying_threads=2</arg> </args> </work> <work kind="silkb" run="jbs" groups="groupA,groupB"> <args> <arg name="distance">120000</arg> <arg name="jbsopt">xmas_size=1200000</arg> </args> </work> </works> </inter> </inters> </abtshop>
尝试的错误代码
import xml.etree.ElementTree as ET tree=ET.parse('test.xml') root = tree.getroot() xm_subs=[] for subn in root.findall(".//inter/works/work[@run='jbs'][@kind='obopay']/../.."): sname=subn.attrib["name"] for subg in root.findall(".//inter[@name='%s']/jobs/job[@run='jbs'][@kind='obopay'][@groups]" % sname): groups=subg.attrib['groups'] for gname in groups.split(","): sub_name=subn.attrib["name"] + "-" + gname xm_subs.append(sub_name) else: xm_subs.append(subn.attrib["name"]) print(xm_subs)
问题点分析
- XPath路径错误:原代码里写了
/jobs/job,但XML中对应的节点是/works/work,导致找不到目标节点 - 循环逻辑错误:
else和外层for绑定,而非判断是否找到带groups的节点,导致即使找到groups,也会额外添加原name值 - 冗余查找:不需要从root重新定位节点,直接从当前
inter节点内部查找更高效
修正后的代码
import xml.etree.ElementTree as ET tree = ET.parse('test.xml') root = tree.getroot() xm_subs = [] # 遍历所有符合条件的inter节点 for inter in root.findall(".//inter[works/work[@run='jbs'][@kind='obopay']]"): inter_name = inter.attrib["name"] # 查找当前inter下符合条件且带groups属性的work节点 work_node = inter.find(".//work[@run='jbs'][@kind='obopay'][@groups]") if work_node is not None: # 拆分组名并拼接 groups = work_node.attrib["groups"].split(",") for group in groups: xm_subs.append(f"{inter_name}-{group}") else: # 没有groups属性,直接添加name xm_subs.append(inter_name) print(xm_subs)
预期输出
['nim_turk', 'nim_us_m-groupA', 'nim_us_m-groupB']
内容的提问来源于stack exchange,提问作者iamsage
相关产品推荐
相关产品推荐

