Valid source code of web pages is an essential foundation for making a complex website look and function properly across various web browser and platforms. For the BLITZ Labs blog we use WordPress as our CMS. Wordpress is a great tool, but it doesn’t always output valid XHTML. Since we have multiple people and multiple departments always adding new content to the blog (many of whom are not XHTML gurus or web standardistas) I needed a way to be notified not only when a new blog entry was added, but when an entry was added that required some code cleanup to make it compliant.
The defacto standard for validating a websites markup is the W3C Markup Validation Service, and using Firefox’s Web Developer Toolbar extension makes validating a website a snap. But developers tend to be a lazy creature, always looking for opportunities to develop new tools to make their (and others) lives easier. I didn’t want to have to manually check that the blogs code was valid each time someone added an entry. I wanted the information to come to me automatically! I wanted the machine to do my work for me. See? I told you we were lazy!
RSS is a great tool for putting machines to work and sending out notifications when something online has changed. There are hundreds of RSS aggregator applications (both desktop, web, and mobile based) that will consume RSS data from anywhere on the web and alert you to any new changes made to your favorite websites. My RSS application of choice is Feed Demon and it’s always running on my computer which makes it the perfect notification tool I needed for the job.
The W3C Validation service provides a SOAP API. The nice thing about SOAP is that it outputs it’s results as XML. RSS also happens to be XML. So all I needed now was a way to consume the W3C validation results (as XML), and transform them into RSS (also XML). Enter XSLT. XSLT does exactly that, it translates one type of XML into a different type of XML.
The ASP.NET framework provides all of the tools necessary to handle SOAP, XML, XSLT, and output to RSS. The entire program is less than 100 lines of code (including the XSL translation instructions). Here is the C# code behind that does all the heavy lifting:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | using System; using System.IO; using System.Net; using System.Text; using System.Xml; using System.Xml.Xsl; namespace ValidatorToRss { public partial class validate : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { //Set Validation URL string url = "http://labs.blitzagency.com/"; if (!string.IsNullOrEmpty(Request.QueryString["uri"])) { url = Request.QueryString["uri"]; } //Create request to validator for URL HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://validator.w3.org/check?uri="+ url +"&output=soap12"); //Receive response from validator HttpWebResponse response = (HttpWebResponse)request.GetResponse(); //Create XML document to store response results XmlDocument xmlDoc = new XmlDocument(); //Load response results into XML document xmlDoc.Load(response.GetResponseStream()); //Close web response to validator response.Close(); //Load XSLT to transform response into RSS XslCompiledTransform xslDoc = new XslCompiledTransform(); xslDoc.Load(Server.MapPath("rss.xsl")); //Create XML writer XmlTextWriter writer = new XmlTextWriter(Response.Output); writer.WriteStartDocument(); //Transform XML response to RSS via XSL and write to screen xslDoc.Transform(xmlDoc, null, writer); } } } |
And here is the rss.xsl file that is used in the translation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:m="http://www.w3.org/2005/10/markup-validator"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" /> <xsl:template match="/env:Envelope/env:Body/m:markupvalidationresponse"> <rss version="2.0"> <channel> <title> W3C Validation for: <xsl:value-of select="m:uri" /> </title> <link> <xsl:value-of select="m:uri" /> </link> <description>Validation service written by Jason Grunstra</description> <ttl>60</ttl> <xsl:for-each select="m:errors/m:errorlist/m:error"> <item> <title> Error: <xsl:value-of select="m:line" />, <xsl:value-of select="m:col" /> </title> <link> http://validator.w3.org/check?uri=<xsl:value-of select="//env:Envelope/env:Body/m:markupvalidationresponse/m:uri" />&charset=(detect+automatically)&doctype=Inline&ss=1&verbose=1#line-<xsl:value-of select="m:line" /> </link> <category>Error</category> <description> <xsl:value-of select="m:message" /> </description> </item> </xsl:for-each> <xsl:for-each select="m:warnings/m:warninglist/m:warning"> <item> <title> Warning: <xsl:value-of select="m:line" />, <xsl:value-of select="m:col" /> </title> <link> http://validator.w3.org/check?uri=<xsl:value-of select="//env:Envelope/env:Body/m:markupvalidationresponse/m:uri" />&charset=(detect+automatically)&doctype=Inline&ss=1&verbose=1#line-<xsl:value-of select="m:line" /> </link> <category>Warning</category> <description> <xsl:value-of select="m:message" /> </description> </item> </xsl:for-each> </channel> </rss> </xsl:template> </xsl:stylesheet> |
The end result is an RSS feed that will return all the errors and warnings from the validation service as RSS items. If your code is valid and there are no errors, the feed will be empty, and that’s a very good thing!
I would link to the hosted version, but the W3C service has a limit on the number of incoming requests, and since I want to keep using this service myself without getting banned, you’ll just have to use the code posted above to create your own hosted service. Here is a sample RSS output that results from validating the Google.com website.
{ 4 comments… read them below or add one }
Hi,
I have tried using your validator script, doesn’t seem to work though. Because the doctype is posted back from W3C the script seems to recognise this and think that it is publishing the doctype twice?
Any ideas would be very much appreciated.
Dale
Dale: Is the issue with the code itself not compiling? Or is it an issue in your RSS reader? If reader, what app are you using?
save to my Bookmarks )
[URL=http://belldasgresham.bravejournal.com - sonic coloring pages[/URL -
spots on feet
http://belldasgresham.bravejournal.com