Skip to content

Commit 5598cc9

Browse files
dfrojasserhiy-storchaka
authored andcommitted
bpo-34160: Preserve order of attributes in minidom. (GH-10219)
1 parent f194479 commit 5598cc9

File tree

4 files changed

+34
-3
lines changed

4 files changed

+34
-3
lines changed

Doc/library/xml.dom.minidom.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ module documentation. This section lists the differences between the API and
143143
For the :class:`Document` node, an additional keyword argument *encoding* can
144144
be used to specify the encoding field of the XML header.
145145

146+
.. versionchanged:: 3.8
147+
The :meth:`writexml` method now preserves the attribute order specified
148+
by the user.
146149

147150
.. method:: Node.toxml(encoding=None)
148151

@@ -156,6 +159,10 @@ module documentation. This section lists the differences between the API and
156159
encoding. Encoding this string in an encoding other than UTF-8 is
157160
likely incorrect, since UTF-8 is the default encoding of XML.
158161

162+
.. versionchanged:: 3.8
163+
The :meth:`toxml` method now preserves the attribute order specified
164+
by the user.
165+
159166
.. method:: Node.toprettyxml(indent="", newl="", encoding="")
160167

161168
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
165172
The *encoding* argument behaves like the corresponding argument of
166173
:meth:`toxml`.
167174

175+
.. versionchanged:: 3.8
176+
The :meth:`toprettyxml` method now preserves the attribute order specified
177+
by the user.
178+
168179

169180
.. _dom-example:
170181

Lib/test/test_minidom.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import copy
44
import pickle
5+
import io
6+
import contextlib
57
from test.support import findfile
68
import unittest
79

@@ -1560,5 +1562,24 @@ def testProcessingInstructionNameError(self):
15601562
pi = doc.createProcessingInstruction("y", "z")
15611563
pi.nodeValue = "crash"
15621564

1565+
def test_minidom_attribute_order(self):
1566+
xml_str = '<?xml version="1.0" ?><curriculum status="public" company="example"/>'
1567+
doc = parseString(xml_str)
1568+
output = io.StringIO()
1569+
doc.writexml(output)
1570+
self.assertEqual(output.getvalue(), xml_str)
1571+
1572+
def test_toxml_with_attributes_ordered(self):
1573+
xml_str = '<?xml version="1.0" ?><curriculum status="public" company="example"/>'
1574+
doc = parseString(xml_str)
1575+
self.assertEqual(doc.toxml(), xml_str)
1576+
1577+
def test_toprettyxml_with_attributes_ordered(self):
1578+
xml_str = '<?xml version="1.0" ?><curriculum status="public" company="example"/>'
1579+
doc = parseString(xml_str)
1580+
self.assertEqual(doc.toprettyxml(),
1581+
'<?xml version="1.0" ?>\n'
1582+
'<curriculum status="public" company="example"/>\n')
1583+
15631584
if __name__ == "__main__":
15641585
unittest.main()

Lib/xml/dom/minidom.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -854,9 +854,8 @@ def writexml(self, writer, indent="", addindent="", newl=""):
854854
writer.write(indent+"<" + self.tagName)
855855

856856
attrs = self._get_attributes()
857-
a_names = sorted(attrs.keys())
858857

859-
for a_name in a_names:
858+
for a_name in attrs.keys():
860859
writer.write(" %s=\"" % a_name)
861860
_write_data(writer, attrs[a_name].value)
862861
writer.write("\"")
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
ElementTree now preserves the attribute order specified by the user.
1+
ElementTree and minidom now preserve the attribute order specified by the user.

0 commit comments

Comments
 (0)