Skip to content

Commit dc04a05

Browse files
authored
bpo-37534: Allow adding Standalone Document Declaration when generating XML documents (GH-14912)
1 parent 0267335 commit dc04a05

File tree

5 files changed

+51
-13
lines changed

5 files changed

+51
-13
lines changed

Doc/library/xml.dom.minidom.rst

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ module documentation. This section lists the differences between the API and
132132
... # Work with dom.
133133

134134

135-
.. method:: Node.writexml(writer, indent="", addindent="", newl="")
135+
.. method:: Node.writexml(writer, indent="", addindent="", newl="",
136+
encoding=None, standalone=None)
136137

137138
Write XML to the writer object. The writer receives texts but not bytes as input,
138139
it should have a :meth:`write` method which matches that of the file object
@@ -144,11 +145,18 @@ module documentation. This section lists the differences between the API and
144145
For the :class:`Document` node, an additional keyword argument *encoding* can
145146
be used to specify the encoding field of the XML header.
146147

148+
Silimarly, explicitly stating the *standalone* argument causes the
149+
standalone document declarations to be added to the prologue of the XML
150+
document.
151+
If the value is set to `True`, `standalone="yes"` is added,
152+
otherwise it is set to `"no"`.
153+
Not stating the argument will omit the declaration from the document.
154+
147155
.. versionchanged:: 3.8
148156
The :meth:`writexml` method now preserves the attribute order specified
149157
by the user.
150158

151-
.. method:: Node.toxml(encoding=None)
159+
.. method:: Node.toxml(encoding=None, standalone=None)
152160

153161
Return a string or byte string containing the XML represented by
154162
the DOM node.
@@ -160,11 +168,14 @@ module documentation. This section lists the differences between the API and
160168
encoding. Encoding this string in an encoding other than UTF-8 is
161169
likely incorrect, since UTF-8 is the default encoding of XML.
162170

171+
The *standalone* argument behaves exactly as in :meth:`writexml`.
172+
163173
.. versionchanged:: 3.8
164174
The :meth:`toxml` method now preserves the attribute order specified
165175
by the user.
166176

167-
.. method:: Node.toprettyxml(indent="\\t", newl="\\n", encoding=None)
177+
.. method:: Node.toprettyxml(indent="\\t", newl="\\n", encoding=None,
178+
standalone=None)
168179

169180
Return a pretty-printed version of the document. *indent* specifies the
170181
indentation string and defaults to a tabulator; *newl* specifies the string
@@ -173,6 +184,8 @@ module documentation. This section lists the differences between the API and
173184
The *encoding* argument behaves like the corresponding argument of
174185
:meth:`toxml`.
175186

187+
The *standalone* argument behaves exactly as in :meth:`writexml`.
188+
176189
.. versionchanged:: 3.8
177190
The :meth:`toprettyxml` method now preserves the attribute order specified
178191
by the user.

Lib/test/test_minidom.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1152,6 +1152,22 @@ def testEncodings(self):
11521152

11531153
doc.unlink()
11541154

1155+
def testStandalone(self):
1156+
doc = parseString('<foo>&#x20ac;</foo>')
1157+
self.assertEqual(doc.toxml(),
1158+
'<?xml version="1.0" ?><foo>\u20ac</foo>')
1159+
self.assertEqual(doc.toxml(standalone=None),
1160+
'<?xml version="1.0" ?><foo>\u20ac</foo>')
1161+
self.assertEqual(doc.toxml(standalone=True),
1162+
'<?xml version="1.0" standalone="yes"?><foo>\u20ac</foo>')
1163+
self.assertEqual(doc.toxml(standalone=False),
1164+
'<?xml version="1.0" standalone="no"?><foo>\u20ac</foo>')
1165+
self.assertEqual(doc.toxml('utf-8', True),
1166+
b'<?xml version="1.0" encoding="utf-8" standalone="yes"?>'
1167+
b'<foo>\xe2\x82\xac</foo>')
1168+
1169+
doc.unlink()
1170+
11551171
class UserDataHandler:
11561172
called = 0
11571173
def handle(self, operation, key, data, src, dst):

Lib/xml/dom/minidom.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,11 @@ class Node(xml.dom.Node):
4343
def __bool__(self):
4444
return True
4545

46-
def toxml(self, encoding=None):
47-
return self.toprettyxml("", "", encoding)
46+
def toxml(self, encoding=None, standalone=None):
47+
return self.toprettyxml("", "", encoding, standalone)
4848

49-
def toprettyxml(self, indent="\t", newl="\n", encoding=None):
49+
def toprettyxml(self, indent="\t", newl="\n", encoding=None,
50+
standalone=None):
5051
if encoding is None:
5152
writer = io.StringIO()
5253
else:
@@ -56,7 +57,7 @@ def toprettyxml(self, indent="\t", newl="\n", encoding=None):
5657
newline='\n')
5758
if self.nodeType == Node.DOCUMENT_NODE:
5859
# Can pass encoding only to document, to put it into XML header
59-
self.writexml(writer, "", indent, newl, encoding)
60+
self.writexml(writer, "", indent, newl, encoding, standalone)
6061
else:
6162
self.writexml(writer, "", indent, newl)
6263
if encoding is None:
@@ -1787,12 +1788,17 @@ def importNode(self, node, deep):
17871788
raise xml.dom.NotSupportedErr("cannot import document type nodes")
17881789
return _clone_node(node, deep, self)
17891790

1790-
def writexml(self, writer, indent="", addindent="", newl="", encoding=None):
1791-
if encoding is None:
1792-
writer.write('<?xml version="1.0" ?>'+newl)
1793-
else:
1794-
writer.write('<?xml version="1.0" encoding="%s"?>%s' % (
1795-
encoding, newl))
1791+
def writexml(self, writer, indent="", addindent="", newl="", encoding=None,
1792+
standalone=None):
1793+
declarations = []
1794+
1795+
if encoding:
1796+
declarations.append(f'encoding="{encoding}"')
1797+
if standalone is not None:
1798+
declarations.append(f'standalone="{"yes" if standalone else "no"}"')
1799+
1800+
writer.write(f'<?xml version="1.0" {" ".join(declarations)}?>{newl}')
1801+
17961802
for node in self.childNodes:
17971803
node.writexml(writer, indent, addindent, newl)
17981804

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,7 @@ David Harrigan
659659
Brian Harring
660660
Jonathan Hartley
661661
Travis B. Hartwell
662+
Henrik Harutyunyan
662663
Shane Harvey
663664
Larry Hastings
664665
Tim Hatch
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
When using minidom module to generate XML documents the ability to add Standalone Document Declaration is added.
2+
All the changes are made to generate a document in compliance with Extensible Markup Language (XML) 1.0 (Fifth Edition) W3C Recommendation (available here: https://www.w3.org/TR/xml/#sec-prolog-dtd).

0 commit comments

Comments
 (0)