Elementtree设置属性顺序


问题内容

我正在尝试编写一个Python脚本来标准化用于配置网站和网站表单的通用XML文件。但是,要做到这一点,我想要么保持元素的原始属性顺序,要么更好地能够以预定义的方式重新排列它们。目前,我尝试将大多数XML解析器的属性顺序重写为字母数字。由于这些XML文件是人工读取/编写和维护的,因此它不太有用。

例如,通用元素在XML中可能看起来像这样;

<Question QuestionRef="XXXXX" DataType="Integer" Text="Question Text" Availability="Shown" DefaultAnswer="X">

但是,一旦通过elementtree并重写为新文件,它将更改为:

<Question Availability="Shown" DataType="Integer" DefaultAnswer="X" PartType="X" QuestionRef="XXXXX" Text="Question Text">

由于脚本的目的是标准化大量XML文件,以提高同事之间的可读性,并且元素属性中包含的信息具有不同的重要性级别(例如,QuestionRef非常重要),因此指出属性需要被明智地命令。

我知道python字典(存储在其中的属性)自然是无序的,而XML规范指出属性的排序是无关紧要的,但这人类可读性的因素是脚本背后的驱动力。

在与该问题类似的其他问题(关于Stack
Overflow)中,我看到它指出pxdom可以做到这一点(问题链接:link),但是我在pxdom文档或使用Google搜索中找不到任何提及方式。那么,有什么方法可以维护属性的顺序或使用当前的XML解析器对其进行定义?最好不要诉诸热补丁:)!

任何人都可以提供的任何帮助将不胜感激:)。


问题答案:

如下所述应用猴子补丁::
ElementTree.py文件中,有一个名为的函数_serialize_xml
在这个功能; 应用以下提到的补丁;

        ##for k, v in sorted(items):  # remove the sorted here
        for k, v in items:
            if isinstance(k, QName):
                k = k.text
            if isinstance(v, QName):
                v = qnames[v.text]
            else:
                v = _escape_attrib(v, encoding)
            write(" %s=\"%s\"" % (qnames[k], v))

这里; 删除sorted(items)并使其items像我上面所做的那样。

还禁用基于命名空间的排序(因为在上述补丁中;当xml属性存在命名空间时,排序仍然存在;否则,如果不存在命名空间;则上述方法工作正常);所以要做到这一点,替换所有{}collections.OrderedDict()ElementTree.py

现在,您已经按顺序将所有属性添加到该xml元素中。

在进行以上所有操作之前; 阅读Fredrik Lundh的版权消息,该消息出现在ElementTree.py