使用ETREE解析XML:获取xl命名空间元素属性值的问题
如何用ElementTree获取XML命名空间属性值?
问题背景
给定简化后的XML文件:
<?xml version="1.0" encoding="UTF-8" ?> <Workplace Type="PP-1" Version="0.2" xmlns:xl="http://www.w3.org/1999/xlink"> <Template xl:actuate="perFile" xl:href="../templates/opt/CMPRfile" xl:show="none" xl:title="CPP1" xl:type="verycomplicated"/> <ProjectID xl:actuate="withtrain" xl:href="filename.ppp" xl:show="none" xl:type="evenmorecomplicated"/> </Workplace>
尝试用ElementTree解析获取xl:href属性值(预期结果为filename.ppp),但以下代码均无效:
xml_namespace = "{http://www.w3.org/1999/xlink}" tree = ET.parse(project_file_name) xml_root_element = tree.getroot() projectid_element = xml_root_element.find(xml_namespace + "ProjectId") # 均无效 value = projectid_element.text value = projectid_element.attrib["href"] value = projectid_element.attrib["xl:href"] print("Value: " + value)
后续尝试通过命名空间查找属性,虽识别到命名空间但未找到目标元素:
tree, ns = parse_and_get_ns(project_file_name) xml_root_element = tree.getroot() print("xml_root_element type: " + str(type(xml_root_element))) print("Namespaces found: ") print(ns) elements = xml_root_element.iterfind("xl:href", ns) print("elements type: " + str(type(elements))) for ele in elements: print("elements ele object type: " + str(type(ele)))
输出:
xml_root_element type: <class 'xml.etree.ElementTree.Element'> Namespaces found: {'xl': '{http://www.w3.org/1999/xlink}'}
解决方案
1. 修正元素查找错误
ProjectID元素属于XML默认命名空间,并非xl命名空间下的元素,因此查找时无需添加xl命名空间前缀。另外注意元素名是大写D的ProjectID,而非代码中的ProjectId(小写d),这会直接导致元素查找失败。
2. 正确获取命名空间属性
ElementTree中,带命名空间的属性键以完整命名空间URI+属性名的形式存储,不会保留xl:href这种前缀格式。因此获取属性时需要用{http://www.w3.org/1999/xlink}href作为键,或者利用已识别的命名空间字典拼接。
正确代码示例
import xml.etree.ElementTree as ET project_file_name = "你的XML文件名.xml" xl_ns = "{http://www.w3.org/1999/xlink}" tree = ET.parse(project_file_name) root = tree.getroot() # 正确查找ProjectID元素(无命名空间,注意大小写) project_id_ele = root.find("ProjectID") if project_id_ele is not None: # 获取xl:href属性 href_value = project_id_ele.attrib[xl_ns + "href"] print("Value:", href_value)
3. 常见错误原因解释
projectid_element.text:属性值并非元素的文本内容,因此无法通过text获取。attrib["href"]:未指定命名空间,ElementTree无法匹配到带xl:前缀的属性。attrib["xl:href"]:ElementTree内部不会保留属性的前缀标识,而是用完整命名空间URI+属性名作为键,因此直接写xl:href无法找到对应属性。iterfind("xl:href", ns):iterfind方法用于查找元素,而非属性,因此无法通过该方式定位属性。
关于xmlns属性
xmlns:xl是命名空间声明属性,属于XML的特殊属性,不会出现在元素的attrib字典中,这是正常现象。
内容的提问来源于stack exchange,提问作者Niels Broertjes
相关产品推荐
相关产品推荐

