使用ElementTree读取XML遇xmlns和xsi标签解析问题
解决ElementTree解析带默认命名空间XML的问题
你的问题根源在于XML中的默认命名空间(xmlns="website6")。ElementTree会将所有属于该命名空间的元素标签格式化为{命名空间URI}标签名,所以直接使用root.find('Survey')这类代码无法匹配到元素。
以下是几种可行的解决方案:
1. 显式指定命名空间字典
创建一个包含命名空间映射的字典,在查找元素时传入该字典,使用前缀:标签名的格式定位元素:
import xml.etree.ElementTree as ET tree = ET.parse(xmlfile) root = tree.getroot() # 定义命名空间映射,前缀可自定义 ns = {'ns': 'website6'} # 查找Survey元素 surveys = root.findall('ns:Survey', ns) for survey in surveys: # 查找Survey下的Header元素 header = survey.find('ns:Header', ns) if header is not None: print(header.text)
2. 自动提取命名空间(避免硬编码)
如果不想硬编码命名空间URI,可以从根元素的标签中自动提取:
import xml.etree.ElementTree as ET tree = ET.parse(xmlfile) root = tree.getroot() # 从根标签中提取命名空间URI ns_uri = root.tag.split('}')[0][1:] ns = {'ns': ns_uri} # 后续查找逻辑同方法1 surveys = root.findall('ns:Survey', ns)
3. 忽略命名空间(不推荐,仅适用于简单场景)
如果不需要保留命名空间信息,可以在解析前移除XML中的命名空间声明,但这种方法可能破坏XML结构,仅适合临时快速处理:
import xml.etree.ElementTree as ET with open(xmlfile, 'r', encoding='utf-8') as f: xml_content = f.read() # 移除默认命名空间声明 xml_content = xml_content.replace(' xmlns="website6"', '') # 解析处理后的内容 root = ET.fromstring(xml_content) # 此时可直接使用标签名查找 surveys = root.findall('Survey')
关键说明
XML默认命名空间会作用于所有未指定前缀的子元素,ElementTree严格遵循XML规范保留命名空间信息,因此必须通过命名空间匹配才能正确定位元素。前两种方法符合XML规范,是推荐的解决方案。
内容的提问来源于stack exchange,提问作者EdwardBurton
相关产品推荐
相关产品推荐

