Displaying a News Feed

You now know enough about the RSS language and how RSS documents are structured that you should be able to put together your own simple web-based news aggregator. To make things more interesting, it's worth designing your news reader so that it can accommodate multiple separate RSS feeds (channels), as opposed to just reading and displaying items from a single document. To make this possible, you need to create a custom XML document to describe each unique feed source.

Creating a News Feed Document

Pulling together multiple RSS feeds into a single XML document doesn't require much information. In fact, all you really need to know is the URL for each RSS document. Listing 24.2 contains the code for an XML document that describes multiple RSS feed sources.

Listing 24.2. An XML Document (feedtest.xml) for Managing RSS Feeds
1: <?xml version="1.0" ?>
2: <?xml-stylesheet href="feeder.xsl" type="text/xsl"?>
4: <feeds>
5:   <feed src="http://www.xyz.com/mmblog.xml"/>
6:   <feed src="http://www.wired.com/news/feeds/rss2/0,2610,,00.xml"/>
7:   <feed src="http://rss.cnn.com/rss/cnn_topstories.rss"/>
8: </feeds>

Notice that the first feed in the feedtest.xml sample document (line 5) is the familiar mmblog.xml document that you created in the previous section.

As you can see, this document is very straightforward in terms of using a custom <feed> tag with a single attribute, src, to represent each unique RSS feed source (lines 5 through 7). All of the feeds in the document are stored within a parent <feeds> tag (line 4), which serves as the root element for the document. Aside from the feeds themselves, the key to this document lies in line 2 where the stylesheet feeder.xsl is linked. This XSLT stylesheet provides all the functionality required to read the feeds, format the content within them, and display the results in a web browser.

Transforming the News Feed for Display

The feedtest.xml sample document doesn't contain much information but it's just enough to grab feed data and transform it for display purposes. The feeder.xsl stylesheet is responsible for reading each feed source in the sample document and processing the RSS code to display the individual news stories in each feed. Listing 24.3 contains the complete code for this XSLT stylesheet.

Listing 24.3. The feeder.xsl XSLT Stylesheet for Transforming RSS Feeds into HTML Web Pages
 1: <?xml version="1.0"?>
 2: <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 3:   <xsl:template match="feeds">
 4:     <html><head><title>Today's News</title></head>
 5:     <style>
 6:       <xsl:comment>
 7:       h1 {
 8:         width=600px;
 9:         font-family:verdana, arial;
10:         font-size:12pt;
11:         font-weight:bold;
12:         color:#FFFFFF;
13:         background-color:#660000;
14:       }
16:       p {
17:         width=600px;
18:         font-family:verdana, arial;
19:         font-size:9pt;
20:         color:#333333;
21:       }
23:       .date {
24:         color:#999999;
25:       }
27:       a:link {
28:         font-weight:bold;
29:         text-decoration:none;
30:         color:#660000;
31:       }
33:       a:hover {
34:         font-weight:bold;
35:         text-decoration:none;
36:         color:#990000;
37:       }
39:       a:visited {
40:         font-weight:bold;
41:         text-decoration:none;
42:         color:#333333;
43:       }
44:       </xsl:comment>
45:     </style>
47:     <body>
48:       <xsl:apply-templates/>
49:     </body>
50:     </html>
51:   </xsl:template>
53:   <xsl:template match="feed">
54:     <xsl:apply-templates select="document(@src)"/>
55:   </xsl:template>
57:   <xsl:template match="channel">
58:     <h1><xsl:value-of select="title"/></h1>
59:     <xsl:apply-templates select="item"/>
60:   </xsl:template>
62:   <xsl:template match="item">
63:     <p>
64:     <xsl:element name="a">
65:       <xsl:attribute name="href">
66:         <xsl:apply-templates select="link"/>
67:       </xsl:attribute>
68:       <xsl:value-of select="title"/>
69:     </xsl:element>
70:     <br />
71:     <xsl:value-of select="description"/>
72:     <br />
73:     <span>
74:     <xsl:if test="pubDate">
75:       <xsl:value-of select="pubDate"/>
76:     </xsl:if>
77:     </span>
78:     </p>
79:   </xsl:template>
80: </xsl:stylesheet>

Similar to other XSLT stylesheets this stylesheet begins with a healthy dose of CSS code thanks to an internal CSS stylesheet (lines 5 through 45) that takes care of formatting the resulting HTML code so that it looks more appealing. This CSS code applies a maroon color scheme with neatly styled headings and story titles, not to mention graying the date of each story so that it doesn't compete as much with the description of the story. You see the visual impact of these styles in just a moment.

Of course, it's important to notice that the code that kicks off the XSLT stylesheet takes place in the feeds template, which is applied to the <feeds> tag in the XML document. In fact, the entire HTML document structure, including the internal CSS style sheet, is contained within the feeds template. This makes sense considering that the <feeds> tag serves as the root element of the feed source XML document.

A much smaller template called feed takes care of transforming each individual feed source. This template simply calls the XSLT document() function while passing in the value of the src attribute (line 54). The end result is that the feed source is read and pulled into the stylesheet where it can be processed as an RSS document. This single line of code is what brings the remaining XSLT templates into play: channel and item.

The channel template simply writes the title of the channel to the HTML page as an <h1> heading tag (line 58), and then hands off the remaining RSS news items to the item template (line 59). From there, the item template does the vast majority of work in terms of transforming RSS data into HTML data that is browser-friendly.

The item template starts by creating an anchor element that serves as a link for the news item title to the actual web resource for the item (lines 64 to 69). The description of the news item is then included as normal paragraph text (line 71), followed by the publish date (lines 73 to 77), which is styled using the CSS date style rule that was defined earlier in the document (lines 23 to 25). Because the <pubDate> tag is optional, an XSLT if conditional is employed to make sure that the publish date is transformed only if it actually exists.

This wraps up the XSLT stylesheet, which you can now use as your own homemade RSS aggregator. Figure 24.4 shows the feedtext.xml example as viewed in Internet Explorer with all of its feeds transformed and cleanly formatted.

Figure 24.4. The sample feed viewer does a decent job of serving as a simplified news aggregator thanks to a clever XSLT stylesheet.

Although I certainly recommended a more full-featured RSS news aggregator for day-to-day news viewing, there's nothing stopping you from using this example as a news aggregator. Just doctor the feedtest.xml document to include your own choice set of RSS feeds, and you're good to go!