12

minidom で XML を処理するときに属性の元の順序を保持する方法はありますか?

私が持っているとしましょう:<color red="255" green="255" blue="233" /> これを minidom で変更すると、属性はアルファベット順に青、緑、赤に再配置されます。元の順序を維持したいと思います。

によって返された要素をループしてファイルを処理してから、elements = doc.getElementsByTagName('color')このような割り当てを行いますe.attributes["red"].value = "233"

4

9 に答える 9

11

属性の順序を維持するために、minidom でこのわずかな変更を行いました。

from collections import OrderedDict

要素クラスで:

__init__(...)
    self._attrs = OrderedDict()
    #self._attrs = {}
writexml(...)
    #a_names.sort()

現在、これは Python 2.7+ でのみ機能します。実際に機能するかどうかはわかりません => 自己責任で使用してください...

また、属性の順序に依存しないように注意してください。

start-tag または empty-element タグ内の属性指定の順序は重要ではないことに注意してください。

于 2011-12-01T17:00:35.210 に答える
3

xml 属性が順序付けられていないことは明らかです。私はちょうどこの奇妙な振る舞いを見つけました!

これは xml.dom.minidom.Element.writexml 関数に追加されたソートに関連しているようです!!

class Element(Node):
... snip ...

    def writexml(self, writer, indent="", addindent="", newl=""):
        # indent = current indentation
        # addindent = indentation to add to higher levels
        # newl = newline string
        writer.write(indent+"<" + self.tagName)

        attrs = self._get_attributes()
        a_names = attrs.keys()
        a_names.sort()
--------^^^^^^^^^^^^^^
        for a_name in a_names:
            writer.write(" %s=\"" % a_name)
            _write_data(writer, attrs[a_name].value)
            writer.write("\"")

行を削除すると、元のドキュメントの順序を維持する動作が復元されます。コードに誤りがないことを diff ツールで確認する必要がある場合は、これをお勧めします。

于 2011-05-06T08:36:58.840 に答える
3

Python 2.7 より前は、次のホットパッチを使用していました

class _MinidomHooker(object):
    def __enter__(self):
        minidom.NamedNodeMap.keys_orig = minidom.NamedNodeMap.keys
        minidom.NamedNodeMap.keys = self._NamedNodeMap_keys_hook
        return self

    def __exit__(self, *args):
        minidom.NamedNodeMap.keys = minidom.NamedNodeMap.keys_orig
        del minidom.NamedNodeMap.keys_orig

    @staticmethod
    def _NamedNodeMap_keys_hook(node_map):
        class OrderPreservingList(list):
            def sort(self):
                pass
        return OrderPreservingList(node_map.keys_orig())

このように使用されます:

with _MinidomHooker():
    document.writexml(...)

免責事項:

  1. 属性の順序に依存してはなりません。
  2. NamedNodeMap クラスの変更はスレッドセーフではありません。
  3. ホットパッチは悪です。
于 2011-12-08T09:47:45.260 に答える
1

1.独自の「Element.writexml」メソッドをカスタマイズします。

「minidom.py」から Element の writexml コードを自分のファイルにコピーします。

名前を writexml_nosort に変更し、

'a_names.sort()' を削除する (python 2.7) か、'a_names = sorted(attrs.keys())' を 'a_names = attrs.keys()' に変更します (python 3.4)

Element のメソッドを独自のものに変更します。

minidom.Element.writexml = writexml_nosort;

2.お気に入りの注文をカスタマイズします。

right_order = ['a', 'b', 'c', 'a1', 'b1']

3. 要素の _attrs を調整します

node._attrs = OrderedDict( [(k,node._attrs[k]) for k in right_order ] )

于 2015-04-17T10:37:44.680 に答える
0

minidom で XML を処理するときに属性の元の順序を保持する方法はありますか?

はい。Python 3.8 以降、XML ドキュメントをシリアライズするときに、元の属性の順序が保持されます。

https://docs.python.org/3/library/xml.dom.minidom.html#xml.dom.minidom.Node.writexmlを参照してください。

于 2020-04-17T08:51:58.963 に答える
-1

minidom の代わりにlxmlライブラリを使用することになりました。

于 2009-06-13T00:11:41.523 に答える