diff --git a/django/utils/feedgenerator.py b/django/utils/feedgenerator.py index 24b2d1d172e..50ede4dd219 100644 --- a/django/utils/feedgenerator.py +++ b/django/utils/feedgenerator.py @@ -187,7 +187,7 @@ class RssFeed(SyndicationFeed): content_type = 'application/rss+xml; charset=utf-8' def write(self, outfile, encoding): - handler = SimplerXMLGenerator(outfile, encoding) + handler = SimplerXMLGenerator(outfile, encoding, short_empty_elements=True) handler.startDocument() handler.startElement("rss", self.rss_attributes()) handler.startElement("channel", self.root_attributes()) @@ -296,7 +296,7 @@ class Atom1Feed(SyndicationFeed): ns = "http://www.w3.org/2005/Atom" def write(self, outfile, encoding): - handler = SimplerXMLGenerator(outfile, encoding) + handler = SimplerXMLGenerator(outfile, encoding, short_empty_elements=True) handler.startDocument() handler.startElement('feed', self.root_attributes()) self.add_root_elements(handler) diff --git a/docs/releases/4.0.txt b/docs/releases/4.0.txt index 4767bdf7bfb..aa82afa4a51 100644 --- a/docs/releases/4.0.txt +++ b/docs/releases/4.0.txt @@ -432,6 +432,10 @@ Miscellaneous * The ``object`` argument of undocumented ``ModelAdmin.log_addition()``, ``log_change()``, and ``log_deletion()`` methods is renamed to ``obj``. +* :class:`~django.utils.feedgenerator.RssFeed`, + :class:`~django.utils.feedgenerator.Atom1Feed`, and their subclasses now + emit elements with no content as self-closing tags. + .. _deprecated-features-4.0: Features deprecated in 4.0 diff --git a/tests/syndication_tests/tests.py b/tests/syndication_tests/tests.py index 6c4fe075063..5a668911f55 100644 --- a/tests/syndication_tests/tests.py +++ b/tests/syndication_tests/tests.py @@ -7,7 +7,9 @@ from django.core.exceptions import ImproperlyConfigured from django.test import TestCase, override_settings from django.test.utils import requires_tz_support from django.utils import timezone -from django.utils.feedgenerator import rfc2822_date, rfc3339_date +from django.utils.feedgenerator import ( + Atom1Feed, Rss201rev2Feed, rfc2822_date, rfc3339_date, +) from .models import Article, Entry @@ -420,6 +422,22 @@ class SyndicationFeedTest(FeedTestCase): published = doc.getElementsByTagName('published')[0].firstChild.wholeText self.assertEqual(published[-6:], '+00:42') + def test_feed_no_content_self_closing_tag(self): + tests = [ + (Atom1Feed, 'link'), + (Rss201rev2Feed, 'atom:link'), + ] + for feedgenerator, tag in tests: + with self.subTest(feedgenerator=feedgenerator.__name__): + feed = feedgenerator( + title='title', + link='https://example.com', + description='self closing tags test', + feed_url='https://feed.url.com', + ) + doc = feed.writeString('utf-8') + self.assertIn(f'<{tag} href="https://feed.url.com" rel="self"/>', doc) + @requires_tz_support def test_feed_last_modified_time_naive_date(self): """