From 5598cc90c745dab827e55fadded42dbe85e31d33 Mon Sep 17 00:00:00 2001 From: Diego Rojas Date: Wed, 7 Nov 2018 09:09:04 -0500 Subject: bpo-34160: Preserve order of attributes in minidom. (GH-10219) --- Doc/library/xml.dom.minidom.rst | 11 +++++++++++ Lib/test/test_minidom.py | 21 +++++++++++++++++++++ Lib/xml/dom/minidom.py | 3 +-- .../2018-10-27-21-11-42.bpo-34160.UzyPZf.rst | 2 +- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/Doc/library/xml.dom.minidom.rst b/Doc/library/xml.dom.minidom.rst index 40470e8..a1f334d 100644 --- a/Doc/library/xml.dom.minidom.rst +++ b/Doc/library/xml.dom.minidom.rst @@ -143,6 +143,9 @@ module documentation. This section lists the differences between the API and For the :class:`Document` node, an additional keyword argument *encoding* can be used to specify the encoding field of the XML header. + .. versionchanged:: 3.8 + The :meth:`writexml` method now preserves the attribute order specified + by the user. .. method:: Node.toxml(encoding=None) @@ -156,6 +159,10 @@ module documentation. This section lists the differences between the API and encoding. Encoding this string in an encoding other than UTF-8 is likely incorrect, since UTF-8 is the default encoding of XML. + .. versionchanged:: 3.8 + The :meth:`toxml` method now preserves the attribute order specified + by the user. + .. method:: Node.toprettyxml(indent="", newl="", encoding="") Return a pretty-printed version of the document. *indent* specifies the @@ -165,6 +172,10 @@ module documentation. This section lists the differences between the API and The *encoding* argument behaves like the corresponding argument of :meth:`toxml`. + .. versionchanged:: 3.8 + The :meth:`toprettyxml` method now preserves the attribute order specified + by the user. + .. _dom-example: diff --git a/Lib/test/test_minidom.py b/Lib/test/test_minidom.py index e91cdba..ad5be2f 100644 --- a/Lib/test/test_minidom.py +++ b/Lib/test/test_minidom.py @@ -2,6 +2,8 @@ import copy import pickle +import io +import contextlib from test.support import findfile import unittest @@ -1560,5 +1562,24 @@ class MinidomTest(unittest.TestCase): pi = doc.createProcessingInstruction("y", "z") pi.nodeValue = "crash" + def test_minidom_attribute_order(self): + xml_str = '' + doc = parseString(xml_str) + output = io.StringIO() + doc.writexml(output) + self.assertEqual(output.getvalue(), xml_str) + + def test_toxml_with_attributes_ordered(self): + xml_str = '' + doc = parseString(xml_str) + self.assertEqual(doc.toxml(), xml_str) + + def test_toprettyxml_with_attributes_ordered(self): + xml_str = '' + doc = parseString(xml_str) + self.assertEqual(doc.toprettyxml(), + '\n' + '\n') + if __name__ == "__main__": unittest.main() diff --git a/Lib/xml/dom/minidom.py b/Lib/xml/dom/minidom.py index e44e04a..469c517 100644 --- a/Lib/xml/dom/minidom.py +++ b/Lib/xml/dom/minidom.py @@ -854,9 +854,8 @@ class Element(Node): writer.write(indent+"<" + self.tagName) attrs = self._get_attributes() - a_names = sorted(attrs.keys()) - for a_name in a_names: + for a_name in attrs.keys(): writer.write(" %s=\"" % a_name) _write_data(writer, attrs[a_name].value) writer.write("\"") diff --git a/Misc/NEWS.d/next/Library/2018-10-27-21-11-42.bpo-34160.UzyPZf.rst b/Misc/NEWS.d/next/Library/2018-10-27-21-11-42.bpo-34160.UzyPZf.rst index 6f3c076..775d33a 100644 --- a/Misc/NEWS.d/next/Library/2018-10-27-21-11-42.bpo-34160.UzyPZf.rst +++ b/Misc/NEWS.d/next/Library/2018-10-27-21-11-42.bpo-34160.UzyPZf.rst @@ -1 +1 @@ -ElementTree now preserves the attribute order specified by the user. +ElementTree and minidom now preserve the attribute order specified by the user. -- cgit v0.12