xmltodict.parse()默认返回dict而非OrderedDict,需显式指定dict_constructor=collections.OrderedDict保序;重复子节点默认单例为dict、复数为list,可用force_list统一为list;命名空间需process_namespaces=True配合namespaces映射简化key;unparse()需pretty=True和二进制写入防乱码。

xmltodict.parse() 为什么返回 dict 而不是 OrderedDict?
默认情况下 xmltodict.parse() 返回的是普通 dict,不是保持顺序的 OrderedDict。这在处理有严格顺序依赖的 XML(比如某些配置文件、SOAP 响应)时会出问题——字段顺序一乱,下游校验或序列化就可能失败。
- 加参数
dict_constructor= collections.OrderedDict才能保序,别忘了先import collections - Python 3.7+ 的
dict虽然插入有序,但xmltodict仍默认用dict构造,不等于自动保序;它内部没做版本适配逻辑 - 如果后续要转回 XML 再比较哈希或做签名,顺序差异会导致
xmltodict.unparse()输出不一致
嵌套同名标签被合并成 list 还是 dict?
xmltodict 对重复子节点的处理策略很关键:当某个父节点下有多个同名子节点(比如 <item></item><item></item>),它默认把它们收进一个 list;但如果只有一个,就直接塞成 dict。这种“单例变标量、复数变列表”的行为,会让代码写起来很别扭。
- 统一行为:传参
force_list=('item', 'entry', 'member'),把指定标签名永远转成list,避免运行时TypeError: 'dict' object is not subscriptable - 注意
force_list接收的是字符串元组或列表,不是正则,不能写'*.item' - 如果 XML 中某处
<item>只出现一次,但你代码里按items[0]访问,不加force_list就会崩
XML 命名空间(namespace)导致 key 名带奇怪前缀
遇到 {http://schemas.example.com/v1}user 这种 key,说明原始 XML 含命名空间,而 xmltodict 默认不做清洗,直接把完整 URI 当作字典 key,既难读又难写死引用。
- 用
process_namespaces=True+namespaces={'http://schemas.example.com/v1': 'v1'}参数,能把 key 缩成v1:user - 但注意:这个缩写只作用于 tag 名,
xmlns属性本身仍保留,不会自动删掉;需要手动 pop 或忽略 - 如果 XML 多个 namespace 混用,且 prefix 冲突(比如两个不同 URI 都声明为
ns),xmltodict无法区分,会覆盖——这时得先预处理 XML 去重 prefix
从 dict 写回 XML 时中文乱码或格式丑得没法看
xmltodict.unparse() 默认输出是紧凑无缩进的单行字符串,且编码设为 utf-8,但如果你直接 print 或写入文件没指定 encoding,或者想加 indent,很容易踩坑。
立即学习“Python免费学习笔记(深入)”;
- 加
pretty=True参数可启用基础缩进(用空格,不可调);想控制缩进宽度?做不到,它没 exposeindent参数 - 写文件时务必用
open(..., 'wb')模式,然后.encode('utf-8'),否则 Windows 下容易多出 BOM 或乱码 - 如果原 XML 有 DOCTYPE 或 processing instruction(如
<?xml version="1.0" encoding="UTF-8"?>),unparse()默认不生成——得手动拼,或换lxml补位










