Python 3.5中ElementTree为何不转义垂直制表符?
嘿,这个问题我之前也踩过坑!xml.etree.ElementTree确实不会自动处理垂直制表符这类XML规范外的控制字符,而XML 1.0明确要求除了\t、\n、\r之外的控制字符必须转义或移除,不然生成的XML就是无效的,后续解析格式化自然会失败。下面给你两个靠谱的解决方案:
解决XML中垂直制表符未转义导致的解析失败问题
核心问题原因
XML规范里,像\v(U+000B,垂直制表符)、\f(U+000C,换页符)这类控制字符属于非法字符,不能直接出现在XML内容中。但xml.etree.ElementTree默认只转义<、>、&、"、'这5个基础字符,对其他控制字符完全不处理,这就导致生成的XML不符合规范,解析器(比如xml.dom.minidom)会直接报错。
方案1:手动转义非法控制字符
把非法字符转换成对应的XML实体引用,比如\v转成(对应它的Unicode编码),这样XML解析器就能正常识别了。
代码示例:
import xml.etree.ElementTree as ET import xml.dom.minidom as MD def escape_xml_control_chars(text): if not text: return text # 转义垂直制表符 text = text.replace('\v', '') # 可选:同时处理换页符等其他非法控制字符 text = text.replace('\f', '') return text # 初始化元素并处理文本 root = ET.Element("root") original_text = "some <&... text with \v vertical tab here" root.text = escape_xml_control_chars(original_text) # 生成XML并格式化 raw_xml = ET.tostring(root, encoding='unicode') formatted_xml = MD.parseString(raw_xml).toprettyxml(indent=" ") print(formatted_xml)
方案2:直接移除非法控制字符
如果这些控制字符对你的业务没用,直接过滤掉更简单:
import xml.etree.ElementTree as ET import xml.dom.minidom as MD import string def filter_invalid_xml_chars(text): if not text: return text # 只保留XML允许的字符:可打印字符 + \t\n\r valid_chars = string.printable + '\t\n\r' return ''.join(char for char in text if char in valid_chars) # 初始化元素并过滤文本 root = ET.Element("root") original_text = "some <&... text with \v vertical tab here" root.text = filter_invalid_xml_chars(original_text) # 生成XML并格式化 raw_xml = ET.tostring(root, encoding='unicode') formatted_xml = MD.parseString(raw_xml).toprettyxml(indent=" ") print(formatted_xml)
额外注意
如果你的Python版本是3.9及以上,ET.tostring()新增了一些参数,但对控制字符的处理逻辑还是没变,所以依然需要手动处理这些非法字符才能保证XML的有效性。
内容的提问来源于stack exchange,提问作者Pavel K
相关产品推荐
相关产品推荐

