lxml是Python中保留XML注释的首选库,需安装后通过XMLParser设置remove_comments=False,并用isinstance(node, etree._Comment)识别注释节点,tostring默认保留注释且支持indent美化输出。

Python标准库中的xml.etree.ElementTree默认会忽略XML注释,无法保留。若需解析并保留注释,必须使用支持注释的解析器——lxml是目前最稳定、易用且广泛支持注释的第三方库。
安装并启用lxml解析器
lxml不是Python内置模块,需先安装:
pip install lxml
然后在解析时显式指定parser参数,并启用注释支持:
立即学习“Python免费学习笔记(深入)”;
```python
from lxml import etree
# 创建支持注释的解析器
parser = etree.XMLParser(strip_cdata=False, remove_comments=False)
tree = etree.parse("example.xml", parser)
root = tree.getroot()
```
识别和提取注释节点
在lxml中,注释是独立的节点类型(etree.Comment),与元素节点并列。遍历子节点时需单独判断:
- 用
isinstance(node, etree._Comment)判断是否为注释节点 - 注释内容通过
node.text获取(不含) - 注释节点可出现在任意层级:根元素前后、元素之间、甚至同级元素中间
示例遍历:
```python
for node in root.iter():
if isinstance(node, etree._Comment):
print(f"注释: {node.text.strip()}")
elif node.tag is not None: # 排除空白文本节点
print(f"元素: {node.tag}")
```
在修改后重新序列化并保留注释
直接调用etree.tostring()默认会保留注释,但要注意:
- 避免使用
method="html"(会丢弃注释);应使用method="xml"(默认值) - 若需美化输出(缩进),用
etree.indent(tree)(lxml 4.5+),它对注释节点友好 - 写入文件时建议指定
encoding和xml_declaration=True保证格式规范
```python
etree.indent(tree)
xml_bytes = etree.tostring(tree, encoding="utf-8", xml_declaration=True)
with open("output.xml", "wb") as f:
f.write(xml_bytes)
```
替代方案说明(不推荐用于注释保留)
xml.etree.ElementTree本身不支持注释保留,即使配合iterparse也无法捕获注释事件;minidom虽能读取注释(Node.COMMENT_NODE),但API笨重、内存占用高、不推荐新项目使用;lxml在性能、功能和易用性上全面胜出,是实际工程中的首选。









