Displaying the News Items for a Particular Syndication Feed The next task that faces us is creating the DisplayNewsItems.aspx Web page. This page should display the titles of the news items in the selected syndication feed as hyperlinks such that when the hyperlink is clicked the description of the news item is shown in the bottom right frame. This task presents us with two primary challenges:
<script language="javascript">
  // display a blank page in the bottom frame when the news items loads
  parent.rbottom.location.href = "about:blank";
</script>
This client-side JavaScript displays a blank page in the bottom right frame whenever DisplayNewsItems.aspx is loaded. To understand why we want to do this consider the following situation that can unfold if we omit this <script>block:
1. The user clicks on a syndication feed from the left frame, thereby loading the feed's news items in the top right frame.
2. The user then clicks one of the news items from the top right frame, thereby loading the news item's details in the bottom right frame.
3. Now the user clicks on a different syndication feed from the left frame, thereby loading the new feed's news items in the top right frame.
At this point, the details from the previous syndication feed's news item are still in the bottom right frame! The above client-side script code alleviates this glitch by "whipping out" the contents of the bottom right frame every time a syndication feed from the left frame is clicked.
Now that we have taken care of that client-side scripting issue, let's turn our attention to adding the needed XML Web controls. Once you have added the XML Web control, set its ID property to xsltNewsItems and its TransformSource property to NewsItems.xslt (the name of the XSLT stylesheet we'll create next). Now, in the Page_Load event handler we need to retrieve the remote RSS syndication file in an XmlDocument instance, and then set the XML Web control's Document property to this XmlDocument instance.
private void Page_Load(object sender, System.EventArgs e)
{
    // See if the news items for this feed are in the Data Cache
   int feedID = Int32.Parse(Request.QueryString["FeedID"]);
   // Connect to the Database to find out the URL to the RSS
   SqlConnection myConnection = new SqlConnection(connection string);
   // Retrieve the SQL URL for the Remote RSS syndication file
   string SQL_QUERY = "SELECT URL, UpdateInterval FROM Feeds " +
     "WHERE FeedID = @FeedID";
   SqlCommand myCommand = new SqlCommand(SQL_QUERY, myConnection);
   SqlParameter feedParam = new SqlParameter("@FeedID",
     SqlDbType.Int, 4);
   feedParam.Value = feedID;
   myCommand.Parameters.Add(feedParam);
   myConnection.Open();
   string feedURL = myCommand.ExecuteScalar().ToString()
   myConnection.Close();
   // Now that we have the feed URL, load it in into an XML document
   XmlDocument feedXML = new XmlDocument();
   feedXML.Load(feedURL);
   xmlNewsItems.Document = feedXML;
}
The most germane lines of code in the Page_Load event handler are the last three. These three lines of code create the new XmlDocument object, load in the remote RSS feed, and assign the XmlDocument object to the XML Web control's Document property. Isn't it impressive how simple it is to access remote XML data and display it in an ASP.NET Web page?
All that we have left to do now is create the XSLT stylesheet, NewsItems.aspx. This first draft of this stylesheet can be seen below:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html" omit-xml-declaration="yes" />
  <xsl:template match="/rss/channel">
   <b><xsl:value-of select="title"
     disable-output-escaping="yes" /></b>
   <xsl:for-each select="item">
    <li>
     <a>
      <xsl:attribute name="href">
       DisplayItem.aspx?ID=<xsl:number value="position()" />
</xsl:attribute>
    <xsl:attribute name="target">rbottom</xsl:attribute>
     <xsl:value-of select="title"
      disable-output-escaping="yes" />
      </a>
    (<xsl:value-of select="pubDate" />)
    </li>
   </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>
This XSLT stylesheet has a single template that matches on the /rss/channel XPath expression, outputting the value of the <title> element in a bold font. Next, it iterates through each of the <item> elements and, for each, displays a hyperlink to DisplayItem.aspx, passing the element's position through the querystring. Note that this hyperlink also has its target attribute set to rbottom, the name of the bottom right frame. Finally, it displays the value of the <pubDate> element after each news item title.
There are a couple of items in the XSLT stylesheet that not everyone may be familiar with. The first of these is the disable-output-escaping="yes" attribute in the elements. Essentially, this attribute setting informs the XSLT engine that it should not escape those illegal XML characters-&, , " and '. To understand what this accomplishes, realize that if this attribute were not set (or was set to the default value, "no"), then if the title contained an escaped & as &, the resulting HTML would have & in it as well, as opposed to just &. If you think about this for a bit, you can see that this can cause a multitude of problems. For example, if the title for a syndication file is: "Matt's <i>Cool</i> Blog", then if output escaping is not disabled, then the output would remain "Matt's <i>Cool</i> Blog" and would be shown in the Web page as, "Matt's <i>Cool</i> Blog". With disable-output-escaping="yes", however, the output is not escaped and is read as "Matt's <i>Cool</i> Blog", thereby displaying in the Web page as the desired "Matt's Cool Blog".
Another thing to note is the <a> element. Realize that this funky syntax ends up generating the following output:
<a href="DisplayItem.aspx?ID=position">news item title</a>
The reason we have to use this syntax is because in order to add an attribute to an element in an XSLT stylesheet you need to create the element and then inside of the element's tags, use the <xsl:attribute> syntax. There are some examples of this syntax available online at W3Schools, The <xsl:attribute> Element page.
Finally, note that the ID querystring value in the hyperlink is assigned the value from the <xsl:number> element, with a value of the position() function. The element simply emits a number. The position() function is an XPath function that returns the ordinal position of the current node in the XML document. This means the first news item will have a position() value of 1; the second, a position() value of 2; and so on. We need to record this value and pass it along via the querystring so that when the DisplayItem.aspx Web page is called, it knows what item from the RSS syndication feed we are interested in viewing.
The astute reader may have realized that our XSLT stylesheet is not complete due to the fact that the FeedID parameter is not passed through the querystring to the DisplayItem.aspx Web page. To see why this is a problem, recall that we are sending in the ID querystring parameter the ordinal position of the element the user is interested in viewing the details for. That is, if the user clicks on the fourth news item, the page DisplayItem.aspx?ID=4 will be loaded in the bottom right frame. The problem is that DisplayItem.aspx cannot determine what feed the user is interested in viewing. There are a couple of ways to figure this out, such as having the bottom right frame use client-side JavaScript to read the URL of the top right frame, thereby ascertaining the value of FeedID. A simpler way, in my opinion, is to merely pass along the FeedID value through the querystring along with the ID parameter.
One difficulty that arises from this is that FeedID is not present in the RSS XML data, which is what the XSLT stylesheet is working with. The DisplayNewsItems.aspx Web page knows the FeedID, though, and needs to somehow let the XSLT stylesheet know this value. This can be accomplished through the use of XSLT parameters.
Using XSLT parameters is fairly straightforward. In the XSLT stylesheet, you need to add inside the <xsl:template> element an <xsl:param> element, which provides the name for the parameter. Let's call this parameter FeedID:
<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/rss/channel">
<xsl:param name="FeedID" />
...
</xsl:template>
</xsl:stylesheet>
Now, the parameter can be used in an <xsl:value-of> element using the following syntax:
<xsl:value-of select="$parameterName" />
Therefore, we can add the FeedID querystring parameter to the hyperlink by adding the following to our existing XSLT stylesheet:
<a>
  <xsl:attribute name="href">DisplayItem.aspx?ID=<xsl:number
   value="position()" /> &FeedID=<xsl:value-of select="$FeedID"
    /></xsl:attribute>
Note that we have an ampersand (escaped to &) after the ID querystring parameter, and then have the querystring parameter FeedID with the value from the FeedID parameter. That's all we have to add to our XSLT stylesheet.
What remains is to set the parameter's value programmatically in the Page_Load event handler of the DisplayNewsItems.aspx Web page. This is accomplished using the XsltArgumentList class. This class contains an AddParameter() method. Once we have created an instance of this class and added the parameter, we simply set the class instance to the XML Web control's TransformArgumentList parameter. The following code shows the updated Page_Load event handler for DisplayNewsItems.aspx:
private void Page_Load(object sender, System.EventArgs e)
{
...
  // Now that we have the feed URL, load it in into an XML document
  XmlDocument feedXML = new XmlDocument();
  feedXML.Load(feedURL);
  xmlNewsItems.Document = feedXML;
  // Add the FeedID parameter to the XSLT stylesheet
  XsltArgumentList xsltArgList = new XsltArgumentList();
  xsltArgList.AddParam("FeedID", "", feedID);
  xmlNewsItems.TransformArgumentList = xsltArgList;}
*This article originally appeared on the ASP.NET Dev Center at MSDN
Scott Mitchell, author of five ASP/ASP.NET books and founder of 4GuysFromRolla.com, has been working with Microsoft Web technologies for the past five years. An active member in the ASP and ASP.NET community, Scott is passionate about ASP and ASP.NET and enjoys helping others learn more about these exciting technologies. For more on the DataGrid, DataList, and Repeater controls, check out Scott's book ASP.NET Data Web Controls Kick Start (ISBN: 0672325012). Read his blog at : http://scottonwriting.net
No comments yet. Be the first to comment!