XML Tutorial · XML in the Real World · Lesson 24 of 28
RSS, Atom and Sitemaps
The XML formats behind web feeds and search-engine sitemaps: reading RSS 2.0 and Atom, and generating a sitemap.xml.
Feeds
Blogs, podcasts and news sites publish feeds so readers and apps can follow updates:
| RSS 2.0 (2002) | Atom (RFC 4287, 2005) | |
|---|---|---|
| Root | <rss version="2.0"><channel> |
<feed xmlns="http://www.w3.org/2005/Atom"> |
| Entry | <item> |
<entry> |
| Date | <pubDate> (RFC 822 format) |
<updated> (ISO 8601) |
| Namespaced | No (extensions use namespaces) | Yes |
Podcasts use RSS 2.0 with the iTunes namespace; YouTube channels publish Atom.
from lxml import etree
feed = etree.fromstring(b"""<rss version="2.0">
<channel>
<title>ReadyCamel blog</title>
<link>https://www.readycamel.com/</link>
<item><title>XML namespaces explained</title><link>https://www.readycamel.com/tutorials/xml/namespaces</link><pubDate>Tue, 20 Oct 2026 09:00:00 GMT</pubDate></item>
<item><title>Streaming large XML files</title><link>https://www.readycamel.com/tutorials/xml/streaming</link><pubDate>Thu, 22 Oct 2026 09:00:00 GMT</pubDate></item>
</channel>
</rss>""")
print(feed.findtext("channel/title"))
for item in feed.iterfind("channel/item"):
print("-", item.findtext("title"), "|", item.findtext("pubDate")[5:16])
Output
ReadyCamel blog - XML namespaces explained | 20 Oct 2026 - Streaming large XML files | 22 Oct 2026
<?php
$feed = simplexml_load_string('<rss version="2.0">
<channel>
<title>ReadyCamel blog</title>
<link>https://www.readycamel.com/</link>
<item><title>XML namespaces explained</title><link>https://www.readycamel.com/tutorials/xml/namespaces</link><pubDate>Tue, 20 Oct 2026 09:00:00 GMT</pubDate></item>
<item><title>Streaming large XML files</title><link>https://www.readycamel.com/tutorials/xml/streaming</link><pubDate>Thu, 22 Oct 2026 09:00:00 GMT</pubDate></item>
</channel>
</rss>');
echo $feed->channel->title, "\n";
foreach ($feed->channel->item as $item) {
echo "- ", $item->title, " | ", substr($item->pubDate, 5, 11), "\n";
}
Output
ReadyCamel blog - XML namespaces explained | 20 Oct 2026 - Streaming large XML files | 22 Oct 2026
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.*;
import java.io.ByteArrayInputStream;
public class Main {
static String text(Element e, String name) {
return e.getElementsByTagName(name).item(0).getTextContent();
}
public static void main(String[] args) throws Exception {
String xml = """
<rss version="2.0">
<channel>
<title>ReadyCamel blog</title>
<link>https://www.readycamel.com/</link>
<item><title>XML namespaces explained</title><link>https://www.readycamel.com/tutorials/xml/namespaces</link><pubDate>Tue, 20 Oct 2026 09:00:00 GMT</pubDate></item>
<item><title>Streaming large XML files</title><link>https://www.readycamel.com/tutorials/xml/streaming</link><pubDate>Thu, 22 Oct 2026 09:00:00 GMT</pubDate></item>
</channel>
</rss>""";
Element channel = (Element) DocumentBuilderFactory.newInstance().newDocumentBuilder()
.parse(new ByteArrayInputStream(xml.getBytes("UTF-8"))).getElementsByTagName("channel").item(0);
System.out.println(text(channel, "title"));
NodeList items = channel.getElementsByTagName("item");
for (int i = 0; i < items.getLength(); i++) {
Element item = (Element) items.item(i);
System.out.println("- " + text(item, "title") + " | " + text(item, "pubDate").substring(5, 16));
}
}
}
Output
ReadyCamel blog - XML namespaces explained | 20 Oct 2026 - Streaming large XML files | 22 Oct 2026
Run this on your computer — see “Get Started” for setup.
Sitemaps
A sitemap lists the pages search engines should crawl (protocol at sitemaps.org).
Limits: 50,000 URLs or 50 MB per file; larger sites use a sitemap index pointing to several files. Search engines
ignore <priority> and <changefreq> today, but use an accurate <lastmod>.
from lxml import etree
NS = "http://www.sitemaps.org/schemas/sitemap/0.9"
pages = [("/tutorials/xml/", "2026-10-22"), ("/tutorials/xml/namespaces", "2026-10-20"),
("/search?q=xml&page=2", "2026-10-21")]
urlset = etree.Element(f"{{{NS}}}urlset", nsmap={None: NS})
for path, modified in pages:
url = etree.SubElement(urlset, f"{{{NS}}}url")
etree.SubElement(url, f"{{{NS}}}loc").text = "https://www.readycamel.com" + path
etree.SubElement(url, f"{{{NS}}}lastmod").text = modified
print(etree.tostring(urlset, pretty_print=True, xml_declaration=True, encoding="UTF-8").decode())
Output
<?xml version='1.0' encoding='UTF-8'?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://www.readycamel.com/tutorials/xml/</loc>
<lastmod>2026-10-22</lastmod>
</url>
<url>
<loc>https://www.readycamel.com/tutorials/xml/namespaces</loc>
<lastmod>2026-10-20</lastmod>
</url>
<url>
<loc>https://www.readycamel.com/search?q=xml&page=2</loc>
<lastmod>2026-10-21</lastmod>
</url>
</urlset>Test yourself
How many URLs can one sitemap file list at most?
50,0001,00010,000Unlimited
Show answer
Answer: 50,000
The sitemap protocol limits a file to 50,000 URLs and 50 MB uncompressed; use a sitemap index beyond that.