I mentioned recently that when I created the comment feed for the blog, I didn't use XmlDocument.
Rewind. When I created the original RSS feed for the blog, I built the XML programmatically, with CreateElement and AppendChild and that sort of thing. I found that kind of tedious, as I was obliged to do a lot of frustrating trial-and-error work. Moreover, as noted in my description, there was the annoying business with having to specify namespaces for some of the elements, etc.
For the comment feed, how would I make this better? The correct answer in every way is "become more expert in using the System.Xml namespace." The Mike answer, tho, is "cheat."
And cheat I did. Scott Hanselman notes that for dasBlog[1], they used the XML serializer to do most of the heavy lifting in converting their blog entry objects into XML (as I am guessing). That's slick, and it's a Jeff Atwood moment ("The real challenge in modern programming isn't sitting down and writing a ton of code; it's figuring out what existing code or frameworks you should be hooking together.").
I took a rather less elegant approach that moreover violates a ton of rules of object orientation and other programming methodologies. (I assume.) What I did was create a text file that contained the template for the comment feed, with placeholders for the content. In the feed handler, I read the template as a text file, then did plain ol' string substitutions to inject the feed content. Then I just fed the whole thing out as a text/xml stream to the browser. Voilà.[2]
For example, here's the text file for the comment feed header:[3]<item>
<title>Comment by %%creator%% on "%%title%%"</title>
<link>%%link%%</link>
<guid>%%guid%%</guid>
<description>%%description%%</description>
<dc:creator>%%creator%%</dc:creator>
<pubDate>%%pubDate%%</pubDate>
</item>
There's a similar template for the comment header/body. Then in code, I filled in the templates. Here's the guts of the bit that creates the elements for individual comments (sorry about the artificial wrapping):For Each drBlogEntryComment as DataRow In dsBlogComments.Tables("blogComments").Rows
thisCommentXml = commentXmlDetailTemplate
thisCommentXml = thisCommentXml.Replace("%%title%%", blogEntryTitle)
thisCommentXml = thisCommentXml.Replace("%%link%%", _
drBlogEntryComment("homePage"))
thisCommentXml = thisCommentXml.Replace("%%description%%", _
context.Server.HtmlEncode(drBlogEntryComment("comment")))
thisCommentXml = thisCommentXml.Replace("%%author%%", "")
thisCommentXml = thisCommentXml.Replace("%%creator%%", _
drBlogEntryComment("name"))
blogCommentDateTime= drBlogEntryComment("commentDate")
thisCommentXml = thisCommentXml.Replace("%%pubDate%%", _
blogCommentDateTime.ToString("r"))
commentGuid = link & "#" & id.ToString() & "_" & _
drBlogEntryComment("commentId") ' Adds bookmark to entry URL
thisCommentXml = thisCommentXml.Replace("%%guid%%", commentGuid)
commentFeedText &= thisCommentXml ' Concatenate to previous comments
Next
' Inject comments into entry at designated spot
commentXmlBodyTemplate = commentXmlBodyTemplate.Replace( _
"<!-- %%Comments%% -->", commentFeedText)
context.Response.ContentType = "text/xml"
context.Response.Write(commentXmlBodyTemplate)
The entire ProcessRequest method for the handler came out at about 120 lines in my one-thing-at-a-time style of coding, and which included the code to read the templates and the blog entries out of the database. I doubt that it's any shorter than it would have been to build the XML by hand. But it was lots easier for me. And no fooling around with namespaces or any of those side issues that clogged up the dynamic XML generation.
The next step might could be to invent some sort of classic ASP-style syntax to be able to create the XML file more-or-less declaratively and just inject the content, something like:<description><%# Eval("description") %></description>
using the kinds of expression syntax we have in ASP.NET 2.0 for injecting data, configuration values, and custom expressions. Talk about yer spaghetti code, ha.