1. Original Entry + Comments2. Write a Comment3. Preview Comment
New comments for this entry are disabled.


March 26, 2006  |  Blind XML  |  3702 hit(s)

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.

[1] Discussion here about whether Blog is masculine (der) or neuter (das) in German.

[2] Not "wallah," sheesh.

[3] BTW, I deliberately chose not to expose commenters' email addreeses.




Phil Weber   26 Mar 06 - 4:00 PM

You may find this helpful/interesting:

http://www.philweber.com/articles/easy_rss_in_vbnet.htm


 
mike   26 Mar 06 - 4:26 PM

Beautiful! Thanks, Phil. Looks like I could learn a lot from reading your blog ... :-)

 
lb   24 Jun 06 - 5:28 AM

have done the same thing at times... ;-)

but if i type '%%creator%%' will that get replaced with your name (in the comment feed?)


 
lb   24 Jun 06 - 5:43 AM

ah i see -- it typed my name...
how about this:

The title of this comment is: %%title%%
the author is %%author%%
the description is %%description%%
a guid look like this: %%guid%%
you're publishing this comment at: %%pubDate%%
a link to it is: %%link%%
i just hope nothing goes wrong by typing this:
<!-- %%Comments%% -->

view http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=1460 to see the result... (or http://www.mikepope.com/blog/AddComment.aspx?blogid=1460 to see the original comment)


 
mike   24 Jun 06 - 8:31 AM

Leon, I'm not sure what you're trying to test, but as you can see, any markup you add to the comment is encoded. I am guessing that perhaps you wanted to see if the replacement was global for both the metainfo and the body of the comment -- ? Anyway.

 
lb   24 Jun 06 - 9:44 PM

d'ya know, if you use "&lt;&lt;" instead of %%, then this side effect would be gone.

 
mike   24 Jun 06 - 9:47 PM

But I'm using %% as a placeholder delimiter so's I can find where to do the subbing at run time. It ain't all automatic or nuthin'.

Assuming I understand what you're saying ...