The portfolio and blog of Mark Anderson, Web Standards Ninja
Site no longer online.

A portal for all your commercial pest control needs. Acurid customer information is categorized by industry, a press area awaits reporters with releases, images, and contact information, a pest identification database helps customers identify their pest problem and a secure area helps Acurid communicate special rates to their national accounts. The site uses a comprehensive backend system to enter news, send alerts to subscribers and maintain pest control data.
http://www.anchorbank.com/
Madison, Wisconsin

AnchorBank.com provides customers with customized rate information, the ability to apply for several Anchor products at once, financial calculators, comprehensive rate tables, delayed stock quotes and a customizable AnchorBank Assistant feature; all with the goal of helping AnchorBank customers make sound financial decisions.
Violence is the first refuge of the incompetent - Issac Asimov

Cartoon by El Pais cartoonist Forges
After a year or so of the Mikasa coffee cup pattern, I decided to revert to a more natural, albeit more literal, interpretation of the doodlehaus. Thanks to Movable Type and the inspiration of an ever-expanding cast of CSS gurus (please see them in the related links at the right), I was able to make the transition quickly.
I’ve also abandoned the flash-based portfolio in leiu of one that’s a Blog that will easily track my work chronologically. The biggest challenge this presents is writing the correct PHP to give the navbar the proper “sticky” states. Currently, when you’re in the portfolio section, both the Archives and Portfolio navigations are highlighted. I’m still working on that. While I’d like to avoid a big ‘ol case statement, I may need to revert to one. The current logic is elegant, but flawed in that the main portfolio page is in the archives folder. I may need to create a separate blog for portfolio entries ala Douglas Bowman.
Future plans for the doodlehaus include an RSS amalgomator (either flash or php based) to pull feeds from all my favorite sites and entering some portfolio items that I haven’t gotten around to posting.
Hope you like it. Cheers!
It seems that the doodlehaus has been found by the spiders of Google. I’ve been neglecting this poor site for several months now, posting little or nothing of substance until today. Today, I returned and noticed that there were some bizarre comments on the site, mostly trying to sell Viagra and other such imporant medical advancements. I mean, what could be more important to me as I get older than the ability to perform in a sexual capacity well into my 90’s. But, I digress.
As I was saying, there were a few spammish comments, but also an actual honest-to-goodness comment on our little article on Returning and Displaying XML from a Stored Procedure. I’m flattered. I also found that the article has been posted on a discussion board or two. Wowzers.
The comment from a visitor known only as Jamie, was that my solution is more convoluted and difficult than it needs to be. I’m going to look into this. I had a feeling that there were far too many proprietary Microsoft objects being instansiated for such a simple thing.
I love the Internet. Thank you Tim Berners-Lee! Oh, and thanks Jamie.
Note: to view the examples in this article, you need to view it with Internet Explorer 6.0, which is the only browser in which this bug occurs.
While working on a project I ran a cross a weird CSS bug. Well, at least it’s weird to me. While creating an unordered list navigation system (like a good little webmonkey), I noticed that each button was displaying an extra 2 pixels of space after each <li> item.
Everything started just fine. I created my unordered list:@import “/css/displayquirk/quirk.css”;
No sweat. The problem comes when I try to wrap the text in <span> tags so that I can replace the text with a background image. So, I add a line of css to suppress the display of the link text like so: li a span{display:none;}. That’s when I get these weird extra spaces in IE6:
So, after a few hours of teeth grinding, I remembered that there is a new article at A List Apart that talks about the Farhner image replacement method. Perhaps it could enlighten me. Indeed it did. I was not familiar with the visibility:hidden property. So I thought “hey, what do I have to lose?” Really that’s what I thought. I even said it out loud. Sure enough, after replacing display:none with visibility:hidden, all my problems were solved.
So what’s going on here? I haven’t a clue, but this seems to solve the problem.
Soon to be a review of the snaztastic new suite of apps from Macromedia. Clunking through Flash as we speak. It’s much more developery than last time. I guess it’s time to break down and get serious about OOP and all that. Ah, well. The blinding light of progress has outed my laziness. Rats.
I’m sure everyone’s had this problem (well, probably not, but hey, I did). You have a super-monkey-riffic SQL server full of bitchin’ data. You also have a standard-issue Redmond-compliant Microsoft server all souped up with the latest and greatest MSXML dll (see previous articles/lamentations). You want to call a stored procedure that will return XML to your page on the server-side where you can then mix it with a dash of XSLT and display the final glamorous result to your users. Sounds easy right? Well, not for an idiot like me. However, I eventually figured it out (and when I say “I”, I mean Nick “Master of the SQL Server” Adair and Brian “Boy Wonder” Leege). Here is our tale.
First of all, Microsoft Transact SQL has a built-in command that returns data in XML format rather than as a recordset. It’s a neato feature and I suggest you play around with it (in a manner that is acceptable to your friendly-neighborhood DBA, that is). The syntax is as follows:
SELECT column1, column2, … , column n FROM table FOR XML AUTO, ELEMENTS
So if you wanted to pull the headlines from your news table, you would write:
SELECT headlines FROM news FOR XML AUTO, ELEMENTS
The last bit, “FOR XML AUTO, ELEMENTS” does something magical and good. Not only does it return the data in XML format, but when you use the ELEMENTS attribute, it uses the column names for the tag names. So our headline query above would return something like the following:
<headline>This is the first headline</headline>
<headline>Here’s another headline</headline>
And so on. Very, very slick. But so what? You don’t spend any more time with the SQL Query Analyzer than you do organizing your sock drawer. What you want is to get that data to your script. Well, you could do it in the ASP page, or you could make your friendly neighborhood DBA very, very happy and use a stored procedure. They’re faster, more secure and they stay crunchy in milk.
So, either write it yourself, or ask your DBA to make a stored procedure that returns data as XML. In the case of our headline query, it would look something like this:
—————————————————
CREATE PROCEDURE getHeadlines AS
SELECT headlines FROM news FOR XML AUTO, ELEMENTS
GO
—————————————————
Don’t forget to grant the proper permissions to the stored procedure, because if you don’t you won’t be able to run it with an ASP script. I can’t tell you how many hours of my life have been wasted trying to debug a script that didn’t have permission to execute the stored procedure it was trying to call. You can relate, can’t you?
The exact syntax will change for your individual situations, but if you already know a little bit of SQL or can communicate with your DBA with a sophisticated system of clicks and whistles, you’re well on your way.
So, now we’ve got a stored procedure that returns XML in super-sexy customized tags. As the kids say, “w00t, w00t.” Now you’ll need an ASP page that can leverage this scalable e-business application (sorry).
This was what always stumped me. ADO is not my strongest suit, so I had a lot of trouble instantiating the correct objects (or whatever it is you do with ADO).
But luckily, I had help and a willingness to learn.
So, without much further ado (get it? bwahahahaha), here’s the script you’ll need, complete with copious commentary:
<%@ LANGUAGE=”VBScript” %>
<%
‘—————————————————————-
‘you’ll need to find a copy of adovbs.inc which is a collection of standard
‘ASP/VBScript variables.
‘—————————————————————-
%>
<!– #include virtual=”/adovbs.inc” –>
<%
Dim comm, xmldom
Dim rcArr
rcArr = Array(”BLANK”, “LOADING”, “LOADED”, “INTERACTIVE”, “COMPLETED”)
‘—————————————————————-
‘create your command object so you can run the stored procedure
‘—————————————————————-
Set comm = Server.CreateObject(”ADODB.Command”)
‘—————————————————————-
‘create your xmldom object to hold the xml that gets returned
‘—————————————————————-
Set xmldom = Server.CreateObject(”Microsoft.XMLDOM”)
‘—————————————————————-
‘create a database connection
‘—————————————————————-
comm.ActiveConnection = “your database connection string here”
comm.CommandType = adCmdText
‘—————————————————————-
’send the output of the stored procedure to the xmldom object
‘—————————————————————-
comm.Properties(”Output Stream”) = xmldom
‘—————————————————————-
’set the encoding. i found out that this is very important.
‘—————————————————————-
comm.Properties(”Output Encoding”) = “ISO-8859-1″
‘—————————————————————-
‘tell your object what the root tag of your
‘xml document will be.
‘—————————————————————-
comm.Properties(”XML Root”) = “DIRECTORY”
‘—————————————————————-
‘call the stored procedure we created above
‘—————————————————————-
comm.CommandText = “getHeadlines”
comm.CommandType = adCmdStoredProc
‘—————————————————————-
‘execute the stored procedure and return the results
‘to a stream
‘—————————————————————-
comm.Execute , , adExecuteStream
‘—————————————————————-
‘create another xmldom object in which you’ll load your xsl stylesheet
‘in this case, our stylesheet is named style.xsl and resides in the same
‘directory as the script
‘—————————————————————-
set xsl = Server.CreateObject(”Microsoft.XMLDOM”)
xsl.async = false
xsl.load(Server.MapPath(”style.xsl”))
‘—————————————————————-
‘use the transformNodeToObject method to combine the
‘xml with the xsl on the server-side to side-step the poor
‘client-side support for xml parsing
‘—————————————————————-
strStuffToPrint = xmldom.transformNodeToObject(xsl,response)
Response.Write stuffToPrint
‘—————————————————————-
‘do a little error checking
‘—————————————————————-
If Err.number <> 0 Then
Response.Write “<p>An error has occurred when trying to establish a database connection:<br>”
Response.Write Err.Description & “</p>”
End If
%>
Here’s the big thing to notice. The line where we combine the XML with the XSL that reads, “strStuffToPrint = xmldom.transformNodeToObject(xsl,response)” was what gave me the most trouble. For a long time I was trying to use the transformNode method, which works if you’re accessing a physical XML file, but not with our “virtual” XML file that is being created by the server. From what I understand, the transformNode method operates in UTF-16 mode while transformNodeToObject plays nice with ISO-8859-1, which is the encoding we chose to return to our comm object.
So, the question then is “why not set the ouput encoding to UTF-16?” Well, gentle reader, believe me when I tell you that I tried and tried and tried. I could dig up the error logs to prove it. It just doesn’t work. So, there you go. I suppose you’ll need an xsl stylesheet, but that’s another whole can of worms entirely. If you want to brush up on XSL, I highly recommend the W3C School’s tutorial. Whew. I’m spent. How about you?
Aha! I’m not insane. It is my suspicion that the server has an old version of the msxml.dll which is not up to w3c snuff. So, just in case you were wondering, the correct options for a XSL stylesheet declaration are:
<xsl:stylesheet version=”1.0″ xmlns:xsl=”http://www.w3.org/1999/XSL/Transform”>
or
<xsl:transform version=”1.0″ xmlns:xsl=”http://www.w3.org/1999/XSL/Transform”>
I guess the moral of this story is this: don’t ever defy the W3C.
I have just discovered that the stylesheet declaration that allows for server-side parsing is wrong.
<xsl:stylesheet xmlns:xsl=”http://www.w3.org/TR/WD-xsl”>
The W3C informs me that this was a working draft. So why then do the correct delcarations not work? Anyone? Grrr.
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Quisque sed felis. Aliquam sit amet felis. Mauris semper, velit semper laoreet dictum, quam diam dictum urna, nec placerat elit nisl in quam. Etiam augue pede, molestie eget, rhoncus at, convallis ut, eros. Aliquam pharetra. Nulla in tellus eget odio sagittis blandit. Maecenas at nisl. Nullam lorem mi, eleifend a, fringilla vel, semper at, ligula. Mauris eu wisi.