用Python编辑XML文件的最佳选择,能保持原格式?

3 投票
2 回答
1323 浏览
提问于 2025-04-18 11:20

我想通过Python来编辑现有的XML配置文件,同时保持文件的格式和里面的注释,这样人类也能看得懂。

我会更新现有的XML元素,改变一些值,还会往文件里添加新的XML元素。

ElementTreelxml这样的XML解析器是编辑XML文件的好工具,但在添加新元素时,你会失去原来的格式和文件里的注释。

使用正则表达式似乎是一个选择,但我知道这在处理XML时并不推荐。

所以我在寻找一种类似于Python风格的XML文件编辑器。有什么好的方法吗?谢谢。

2 个回答

0

我建议你使用SAX解析器来解析XML文档,这样你可以灵活地进行修改,并且可以把文档写回去,保持原样。

可以看看xml.sax模块(参考Python的文档)。

0

我最近写了一个类,使用jinja2来格式化通过lxml解析的xml文件,目的是让它变成特定的格式。如果你能把xml文档的实际格式写成代码,你就可以根据自己的需要来修改它:

class XMLWriter:
    def __init__(self):
        self.env = jinja2.Environment()
        self.env.filters['depth'] = lambda node: len(list(node.iterancestors('*')))
        self.env.filters['is_comment'] = lambda node: node.tag is etree.Comment
        self.template = """<?xml version="1.0" encoding="utf-8"?>
{%- for node in rootnode recursive -%}
  {{- '\n' + '  '*node|depth -}}
  {%- if node|is_comment -%}
    {{- node -}}
  {%- else -%}
    <{{- node.tag -}}
    {%- for key,value in node.attrib.iteritems() -%}
      {{ '\n  ' + '  '*node|depth }}{{ key }}="{{ value }}"
    {%- endfor -%}
    {% if node|count %}>{% endif %}
    {{- loop(node) -}}
    {% if node|count %}{{ '\n' + '  '*node|depth }}</{{ node.tag }}>{% else %}/>{%- endif -%}
  {%- endif -%}
{%- endfor -%}"""

    def __call__(self, rootnode):
        return self.serialize(rootnode)
    def serialize(self, rootnode):
        return self.env.from_string(self.template).render(rootnode=[rootnode])

你可以这样使用这个类:

from lxml import etree
root = etree.fromstring(xml_to_parse, parser=etree.ETCompatXMLParser(remove_comments=False))
# do any modifications you like
writer = XMLWriter()
formatted_result = writer(root)

撰写回答