Skip to content

bpo-34160: Preserves order of minidom of Element attributes #10219

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 7, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions Doc/library/xml.dom.minidom.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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
Expand All @@ -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:

Expand Down
21 changes: 21 additions & 0 deletions Lib/test/test_minidom.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import copy
import pickle
import io
import contextlib
from test.support import findfile
import unittest

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

def test_minidom_attribute_order(self):
xml_str = '<?xml version="1.0" ?><curriculum status="public" company="example"/>'
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 = '<?xml version="1.0" ?><curriculum status="public" company="example"/>'
doc = parseString(xml_str)
self.assertEqual(doc.toxml(), xml_str)

def test_toprettyxml_with_attributes_ordered(self):
xml_str = '<?xml version="1.0" ?><curriculum status="public" company="example"/>'
doc = parseString(xml_str)
self.assertEqual(doc.toprettyxml(),
'<?xml version="1.0" ?>\n'
'<curriculum status="public" company="example"/>\n')

if __name__ == "__main__":
unittest.main()
3 changes: 1 addition & 2 deletions Lib/xml/dom/minidom.py
Original file line number Diff line number Diff line change
Expand Up @@ -854,9 +854,8 @@ def writexml(self, writer, indent="", addindent="", newl=""):
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("\"")
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ElementTree now preserves the attribute order specified by the user.
ElementTree and minidom now preserve the attribute order specified by the user.