如何使用xmltodict的parse方法来解析XML文档中的属性选项?
- 内容介绍
- 相关推荐
本文共计952个文字,预计阅读时间需要4分钟。
很多人上来就直接使用 `xmltodict.parse(xml_str)`,发现XML中的 `id` 属性。
要让属性进字典,必须传 xml_attribs=True:
import xmltodict data = xmltodict.parse('<user id="123" type="admin"><name>Alice</name></user>', xml_attribs=True)
这时 data['user']['@id'] 是 "123",data['user']['@type'] 是 "admin"。注意属性全被挂到 @xxx 键下,这是固定前缀,不能改。
属性和子元素同名时,@xxx 和 xxx 会并存,别误判为重复键
XML 允许 <item id="1"><id>2</id></item> 这种写法。启用 xml_attribs=True 后,解析结果里 item 字典会同时有 @id 和 id 两个键,值不同。
立即学习“Python免费学习笔记(深入)”;
常见踩坑:用 for k in data['item']: 遍历时以为 id 是唯一字段,结果漏掉属性或覆盖子元素内容。
- 属性永远走
@xxx路径,子元素走xxx路径,二者不冲突但需主动区分 - 如果业务上属性和子元素语义相同(比如都表示 ID),得在解析后手动合并,xmltodict 不做自动去重
-
xml_attribs=False时,属性彻底消失,连@键都不会出现
嵌套层级深时,@ 前缀容易被忽略,查不到属性就先 print(type(data))
XML 套三四层标签后,比如 <a><b attr="x"><c>text</c></b></a>,启用 xml_attribs=True 后,attr 在 data['a']['b']['@attr'],不是 data['a']['@attr']。
新手常犯错误:对着原始 XML 直接猜路径,没实际打印结构就写 data.get('@id') 或 data['root'].get('@id'),结果是 KeyError 或 None。
- 务必先
print(data)或pprint(data)看清嵌套结构 - 属性只属于它所在 XML 标签的直接父字典,不会“透传”到上层
- 如果 XML 有命名空间(
xmlns:ns="..."),属性前缀可能变成@ns:attr,更得看实际输出
force_list 和 xml_attribs 一起用时,属性仍挂在每个列表项的字典里
遇到多个同名标签(如 <item id="1"/><item id="2"/>),默认会被转成 list,但属性不会丢失——只要开了 xml_attribs=True,每个 list 里的 dict 都带 @id。
示例:
xml = '<root><item id="1"/><item id="2"/></root>' data = xmltodict.parse(xml, xml_attribs=True, force_list=['item'])
此时 data['root']['item'][0]['@id'] == "1",data['root']['item'][1]['@id'] == "2"。
容易忽略的点:
-
force_list只影响结构(是否强制为 list),不影响属性提取逻辑 - 如果没设
force_list,单个<item>会是 dict;两个以上会自动变 list —— 属性依然存在,但代码要兼容两种类型 - 想统一处理,建议始终配
force_list,避免运行时类型判断
@ 前缀写没写对、嵌套位置找没找准。少检查任何一处,拿到的都是半截数据。本文共计952个文字,预计阅读时间需要4分钟。
很多人上来就直接使用 `xmltodict.parse(xml_str)`,发现XML中的 `id` 属性。
要让属性进字典,必须传 xml_attribs=True:
import xmltodict data = xmltodict.parse('<user id="123" type="admin"><name>Alice</name></user>', xml_attribs=True)
这时 data['user']['@id'] 是 "123",data['user']['@type'] 是 "admin"。注意属性全被挂到 @xxx 键下,这是固定前缀,不能改。
属性和子元素同名时,@xxx 和 xxx 会并存,别误判为重复键
XML 允许 <item id="1"><id>2</id></item> 这种写法。启用 xml_attribs=True 后,解析结果里 item 字典会同时有 @id 和 id 两个键,值不同。
立即学习“Python免费学习笔记(深入)”;
常见踩坑:用 for k in data['item']: 遍历时以为 id 是唯一字段,结果漏掉属性或覆盖子元素内容。
- 属性永远走
@xxx路径,子元素走xxx路径,二者不冲突但需主动区分 - 如果业务上属性和子元素语义相同(比如都表示 ID),得在解析后手动合并,xmltodict 不做自动去重
-
xml_attribs=False时,属性彻底消失,连@键都不会出现
嵌套层级深时,@ 前缀容易被忽略,查不到属性就先 print(type(data))
XML 套三四层标签后,比如 <a><b attr="x"><c>text</c></b></a>,启用 xml_attribs=True 后,attr 在 data['a']['b']['@attr'],不是 data['a']['@attr']。
新手常犯错误:对着原始 XML 直接猜路径,没实际打印结构就写 data.get('@id') 或 data['root'].get('@id'),结果是 KeyError 或 None。
- 务必先
print(data)或pprint(data)看清嵌套结构 - 属性只属于它所在 XML 标签的直接父字典,不会“透传”到上层
- 如果 XML 有命名空间(
xmlns:ns="..."),属性前缀可能变成@ns:attr,更得看实际输出
force_list 和 xml_attribs 一起用时,属性仍挂在每个列表项的字典里
遇到多个同名标签(如 <item id="1"/><item id="2"/>),默认会被转成 list,但属性不会丢失——只要开了 xml_attribs=True,每个 list 里的 dict 都带 @id。
示例:
xml = '<root><item id="1"/><item id="2"/></root>' data = xmltodict.parse(xml, xml_attribs=True, force_list=['item'])
此时 data['root']['item'][0]['@id'] == "1",data['root']['item'][1]['@id'] == "2"。
容易忽略的点:
-
force_list只影响结构(是否强制为 list),不影响属性提取逻辑 - 如果没设
force_list,单个<item>会是 dict;两个以上会自动变 list —— 属性依然存在,但代码要兼容两种类型 - 想统一处理,建议始终配
force_list,避免运行时类型判断
@ 前缀写没写对、嵌套位置找没找准。少检查任何一处,拿到的都是半截数据。
