Read XML feeds from a URL
Problem
You need to fetch XML from the web and extract data from it. A common case is reading an RSS or Atom feed.
Solution
Use Jsoup.connect(. When the server sends an XML content type, jsoup will use the XML parser automatically.
Document feed = Jsoup.connect("https://example.com/feed.xml").get();
for (Element entry : feed.select("channel > item, feed > entry")) {
String title = entry.expectFirst("title").text();
Element atomLink = entry.selectFirst("link[href]");
Element rssLink = entry.selectFirst("link:not([href])");
String link = atomLink != null ? atomLink.attr("abs:href") :
rssLink != null ? rssLink.text() : "";
Element date = entry.selectFirst("updated, published, pubDate");
String dateText = date != null ? date.text() : "";
System.out.printf("%s <%s> %s%n", title, link, dateText);
}
Description
The HTML parser is for HTML documents. It knows the HTML rules, and will build a normal HTML document around the input, with html, head, and body elements. It also knows that some HTML tags have special behavior. For example, in HTML, <link> is a metadata element and does not contain text.
That is not what you want for feeds. In RSS, <link> is often the element that contains the article URL:
<item>
<title>New release</title>
<link>https://example.com/news/new-release</link>
</item>
If that is parsed as HTML, the <link> element is treated like an HTML <link> tag. Its text will not be inside the link element. If it is parsed as XML, the tree stays as the feed wrote it, and entry.selectFirst( gives you the URL.
When a response has an XML content type, such as application/rss+xml, application/atom+xml, application/xml, text/xml, or another +xml type, jsoup switches from the HTML parser to the XML parser for that response. The XML parser does not add an HTML shell, and it preserves XML names and output.
RSS and Atom use different element shapes for links. RSS usually has a <link> element whose text is the URL. Atom usually has a <link href="..."> element. The example handles both in one loop.
If a server sends XML with the wrong content type, set the parser explicitly:
Document feed = Jsoup.connect("https://example.com/feed")
.parser(Parser.xmlParser())
.get();
Once parsed, you can use the same jsoup DOM methods, CSS selectors, and abs: URL resolution that you use with HTML.