6

我正在尝试编写一个 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 dicts(存储哪些属性)自然是无序的,并且 XML 规范声明属性排序无关紧要,但这人类可读性因素是脚本背后的驱动力。

在与此类似的其他问题(关于堆栈溢出)中,我看到它指出 pxdom 可以做到这一点(问题链接:链接),但我在 pxdom 文档或使用谷歌搜索中找不到任何关于如何做到这一点的提及. 那么有什么方法可以维护属性的顺序或用当前的 XML 解析器定义它吗?最好不要求助于热补丁:)!

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

4

1 回答 1

9

如下所述应用猴子补丁::
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()fromElementTree.py

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

在执行上述所有操作之前;阅读 Fredrik Lundh 的版权信息ElementTree.py

于 2013-01-10T13:15:36.253 回答