diff --git a/django/test/utils.py b/django/test/utils.py
index 3a630a8109..819e423326 100644
--- a/django/test/utils.py
+++ b/django/test/utils.py
@@ -537,7 +537,8 @@ def compare_xml(want, got):
"""
Try to do a 'xml-comparison' of want and got. Plain string comparison
doesn't always work because, for example, attribute ordering should not be
- important. Ignore comment nodes and leading and trailing whitespace.
+ important. Ignore comment nodes, document type node, and leading and
+ trailing whitespaces.
Based on https://github.com/lxml/lxml/blob/master/src/lxml/doctestcompare.py
"""
@@ -575,7 +576,7 @@ def compare_xml(want, got):
def first_node(document):
for node in document.childNodes:
- if node.nodeType != Node.COMMENT_NODE:
+ if node.nodeType not in (Node.COMMENT_NODE, Node.DOCUMENT_TYPE_NODE):
return node
want = want.strip().replace('\\n', '\n')
diff --git a/docs/topics/testing/tools.txt b/docs/topics/testing/tools.txt
index dd96981504..ad31c0bb9f 100644
--- a/docs/topics/testing/tools.txt
+++ b/docs/topics/testing/tools.txt
@@ -1645,8 +1645,8 @@ your test suite.
syntax differences. When invalid XML is passed in any parameter, an
``AssertionError`` is always raised, even if both string are identical.
- XML declaration and comments are ignored. Only the root element and its
- children are compared.
+ XML declaration, document type, and comments are ignored. Only the root
+ element and its children are compared.
Output in case of error can be customized with the ``msg`` argument.
diff --git a/tests/test_utils/tests.py b/tests/test_utils/tests.py
index f07c0dcd53..32007ebeb2 100644
--- a/tests/test_utils/tests.py
+++ b/tests/test_utils/tests.py
@@ -920,6 +920,11 @@ class XMLEqualTests(SimpleTestCase):
xml2 = "foo bar"
self.assertXMLNotEqual(xml1, xml2)
+ def test_doctype_root(self):
+ xml1 = ''
+ xml2 = ''
+ self.assertXMLEqual(xml1, xml2)
+
class SkippingExtraTests(TestCase):
fixtures = ['should_not_be_loaded.json']