如何使用Python Minidom提取XML中Legal_Name_Data下的姓名信息?
问题:提取XML中wd:Legal_Name_Data节点下的姓名信息
需求:使用Python的xml minidom解析XML文件,仅提取wd:Legal_Name_Data节点下的wd:First_Name和wd:Last_Name,忽略wd:Preferred_Name_Data及其他姓名节点。
待解析XML示例(单条记录):
<?xml version="1.0" encoding="UTF-8"?> <env:Envelope xmlns:env="http://schema.xmlsoap.org/soap/envelope/"> <env:Body> <wd:Get_Working_Response xmlns:wd="urn:com.workway/bsvc" wd:version="v40.1"> <wd:Request_Criteria> <wd:Transaction_Log_Criteria_Data> </wd:Transaction_Log_Criteria_Data> <wd:Field_And_Parameter_Criteria_Data> </wd:Field_And_Parameter_Criteria_Data> <wd:Eligibility_Criteria_Data> </wd:Eligibility_Criteria_Data> </wd:Request_Criteria> <wd:Response_Filter> </wd:Response_Filter> <wd:Response_Group> </wd:Response_Group> <wd:Response_Results> </wd:Response_Results> <wd:Response_Data> <wd:Worker> <wd:Worker_Reference> <wd:ID wd:type="WID">787878787878787</wd:ID> <wd:ID wd:type="Employee_ID">123456</wd:ID> </wd:Worker_Reference> <wd:Worker_Descriptor>John Smith</wd:Worker_Descriptor> <wd:Worker_Data> <wd:Worker_ID>123456</wd:Worker_ID> <wd:User_ID>jsmith</wd:User_ID> <wd:Personal_Data> <wd:Name_Data> <wd:Legal_Name_Data> <wd:Name_Detail_Data wd:Formatted_Name="John J. Smith" wd:Reporting_Name="John J. Smith"> <wd:Country_Reference> <wd:ID wd:type="WID">89989898989989898</wd:ID> <wd:ID wd:type="ISO_3166-1_Alpha-2_Code">US</wd:ID> <wd:ID wd:type="ISO_3166-1_Alpha-3_Code">USA</wd:ID> <wd:ID wd:type="ISO_3166-1_Numeric-3_Code">000000</wd:ID> </wd:Country_Reference> <wd:First_Name>John</wd:First_Name> <wd:Middle_Name>J.</wd:Middle_Name> <wd:Last_Name>Smith</wd:Last_Name> </wd:Name_Detail_Data> </wd:Legal_Name_Data> <wd:Preferred_Name_Data> <wd:Name_Detail_Data wd:Formatted_Name="Johnny James Smith" wd:Reporting_Name="Johnny James Smith"> <wd:Country_Reference> <wd:ID wd:type="WID">89989898989989898</wd:ID> <wd:ID wd:type="ISO_3166-1_Alpha-2_Code">US</wd:ID> <wd:ID wd:type="ISO_3166-1_Alpha-3_Code">USA</wd:ID> <wd:ID wd:type="ISO_3166-1_Numeric-3_Code">000000</wd:ID> </wd:Country_Reference> <wd:First_Name>Johnny</wd:First_Name> <wd:Middle_Name>James</wd:Middle_Name> <wd:Last_Name>Smith</wd:Last_Name> </wd:Name_Detail_Data> </wd:Preferred_Name_Data> <wd:Additional_Name_Data> <wd:Name_Detail_Data wd:Formatted_Name="John J. Smith" wd:Reporting_Name="John J. Smith"> <wd:Country_Reference> <wd:ID wd:type="WID">89989898989989898</wd:ID> <wd:ID wd:type="ISO_3166-1_Alpha-2_Code">US</wd:ID> <wd:ID wd:type="ISO_3166-1_Alpha-3_Code">USA</wd:ID> <wd:ID wd:type="ISO_3166-1_Numeric-3_Code">840</wd:ID> </wd:Country_Reference> <wd:First_Name>John</wd:First_Name> <wd:Middle_Name>J.</wd:Middle_Name> <wd:Last_Name>Smith</wd:Last_Name> </wd:Name_Detail_Data> <wd:Name_Type_Reference> <wd:ID wd:type="WID">89989898989989898</wd:ID> <wd:ID wd:type="Additional_Name_Type_ID">Preferred</wd:ID> </wd:Name_Type_Reference> </wd:Additional_Name_Data> </wd:Name_Data> </wd:Personal_Data> </wd:Worker_Data> </wd:Worker> </wd:Response_Data> </wd:Get_Working_Response> </env:Body> </env:Envelope>
原有代码(会提取所有姓名节点):
from xml.dom import minidom doc = minidom.parse('myfile.xml') firstlist =[] lastlist=[] first = doc.getElementsByTagName('wd:First_Name') for name in first: first2 =name.firstChild.nodeValue firstlist.append(first2) last = doc.getElementsByTagName('wd:Last_Name') for lasts in last: last2 =lasts.firstChild.nodeValue lastlist.append(last2)
解决方案
核心思路是先定位到目标父节点wd:Legal_Name_Data,再在其内部查找子节点,而非全局搜索所有姓名节点。
修改后的代码:
from xml.dom import minidom doc = minidom.parse('myfile.xml') firstlist = [] lastlist = [] # 获取所有Legal_Name_Data节点,缩小搜索范围 legal_name_nodes = doc.getElementsByTagName('wd:Legal_Name_Data') for legal_node in legal_name_nodes: # 仅在当前Legal_Name_Data节点内查找First_Name first_names = legal_node.getElementsByTagName('wd:First_Name') if first_names: firstlist.append(first_names[0].firstChild.nodeValue) # 仅在当前Legal_Name_Data节点内查找Last_Name last_names = legal_node.getElementsByTagName('wd:Last_Name') if last_names: lastlist.append(last_names[0].firstChild.nodeValue) # 输出结果 print("合法名(名):", firstlist) print("合法名(姓):", lastlist)
代码说明
- 先通过
getElementsByTagName('wd:Legal_Name_Data')锁定所有合法姓名节点,避免全局搜索带来的无关数据; - 遍历每个合法姓名节点,在节点内部调用
getElementsByTagName,确保只获取该节点下的子节点; - 添加非空判断,防止因节点缺失导致的报错。
如果需要结构化存储每个Worker的合法姓名,可改用字典列表形式:
from xml.dom import minidom doc = minidom.parse('myfile.xml') legal_names = [] legal_name_nodes = doc.getElementsByTagName('wd:Legal_Name_Data') for legal_node in legal_name_nodes: first_name = legal_node.getElementsByTagName('wd:First_Name')[0].firstChild.nodeValue if legal_node.getElementsByTagName('wd:First_Name') else None last_name = legal_node.getElementsByTagName('wd:Last_Name')[0].firstChild.nodeValue if legal_node.getElementsByTagName('wd:Last_Name') else None legal_names.append({ "first_name": first_name, "last_name": last_name }) print("合法姓名列表:", legal_names)
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

