Active Server Pages+ (ASP+) promises to change the face of Web development, but for now most ASP-based applications are still being developed the same way they were in early 1997 when MicrosoftÂ® Internet Information Server (IIS) 3.0 and ASP were first introduced. Elsewhere there have been many innovations, including Dynamic HTML (DHTML), Microsoft Transaction Services (MTS), XML, and most recently COM+ and IIS 5.0 (as part of WindowsÂ® 2000).
If youï¿½ve been reading about XML, you probably know that it is considered ideal for business-to-business and other complex systems, yet so far youï¿½ve seen little use of XML and XSL in smaller Internet applications, normally the domain of ASP. You may also know that XML and XSL are applicable for server-based, cross-browser applications. You know itï¿½s possible, but why bother when you have ASP sitting in your back pocket, ready to go?
Is there a reason to choose something other than ASP? Is it time to break out of traditional ASP-based development in favor of something better and more powerful? Should you hang up your Response.Write hat and pick up something new? In a word: yes. This article presents nine reasons why you should consider moving away from the traditional approach of combining ADO, ASP, and HTML in favor of designs based on the use of XML and XSL. The samples included here will help to show you how.
A Quick Comparison
First, letï¿½s do a quick review. Figure 1 shows a model of the typical ASP-based approach to application development: retrieve data using ADO and then add presentation-level HTML while looping through the recordset. For the purpose of comparison in the next section, letï¿½s whip up some ASP that renders a table of authors from the pubs database (the sample database that ships with SQL Serverâ¢ 6.5 and higher). The code in Figure 2 should be pretty familiar. It produces a table of authors, as shown in Figure 3.
Figure 1 ASP
Figure 3 Authors Table
Letï¿½s look at the code that produces the same table using XML and XSL. Figure 4 shows the model for the modified approachâ"the straight ASP layer has been replaced with XML, XSL, and ASP.
You could implement this example with SQL Server 2000 since it can return XML from a SQL query instead of returning an ADO recordset (see "SQL Server 2000: New XML Features Streamline Web-centric App Development" in the March 2000 issue of MSDNÂ® Magazine), but you donï¿½t have to wait until your company migrates to SQL Server 2000. Instead, weï¿½ve written a generic function that transforms an ADO recordset into XML. Use ADO as you usually do to retrieve a recordset, then call RecordsetToXMLDoc to convert it into XML. (The source code for this RecordsetToXMLDoc function can be found in the XML Helper Functions section later in this article.) The resulting XML document has a root node of NodeName with an s appended to it (that is, the plural of NodeName). Each row in the recordset rs resides in its own node called NodeName and each of the recordsetï¿½s fields are child nodes of the NodeName element.
Figure 4 XML + XSL
After getting the data back in XML, we need to perform a transformation with an XSL stylesheet. The function TransformXML, which you will also find in the XML Helper Functions section, transforms the source document (XML) using the stylesheet (XSL). The great thing about this function is that the input parameters can be XML strings, XML documents, or the relative paths to files (the function will call Server.MapPath to resolve a relative file path). This flexibility makes the function very useful.
Figure 4 shows a model of the steps required when using XML and XSL. ADO is still used to retrieve the data, but it is converted to XML if the data isnï¿½t already in that form. An XSL stylesheet is applied, and the resulting HTML is sent to the client. There are more steps involved here, but the helper functions provided make the difference negligible.
Figure 5 shows the new ASP code from straightxml1.asp, and the stylesheet authors.xsl is shown in Figure 6. The XML output is exactly the same data as you saw in the dialog in Figure 3.
Letï¿½s compare these approaches. In both cases, you write a SQL query to retrieve the information. Using the traditional ASP approach, you then loop through a recordset and produce HTML. The XML/XSL approach converts the recordset into XML and then applies an XSL transformation to produce HTML.
Before we move on, letï¿½s apply a different view to the XML/XSL approach to give you an appreciation of the flexibility offered by XSL. If you apply the default stylesheet that Microsoft Internet Explorer uses to display XML, the result will be the page shown in Figure 7.
Figure 7 Default Stylesheet
You can find the stylesheet at http://msdn.microsoft.com/xml/samples/defaultss/defaultss.xsl. Weï¿½ve provided a version of straightxml1.asp, called straightxml2.asp, for you to download from the link at the top of this article. The code in straightxml2.asp is identical to straightxml1.asp, which you saw in Figure 5, except that the stylesheet applied is defaultss.xsl stylesheet rather than authors.xsl.
The XML Helper Functions To help you understand how the XML/XSL sample is implemented, this section describes several extremely useful functions in your XML toolbox. All of these functions can be found in the xmlutil.asp file that is available for download from the link at the top of this article.
While there are many tools becoming available to provide XML directly to data consumers, there will always be cases where you need to roll your own XML. The AddXMLNode function shown in Figure 8 does most of the work for you. Note that we prefer to make all of our XML tags lowercase. Because XML is case-sensitive, this helps to avoid unnecessary coding mistakes. Also note the use of the Namespace parameter in the AddXMLNodeEx functionâ"this is necessary if you want this node to use a different namespace than the default namespace for the document.
Youï¿½ll find the RecordsetToXML function invaluable if youï¿½re working at the data tier and need to send XML back to the middle tier (see Figure 9).
As we mentioned earlier, one of the great things about TransformXML is that the two input parameters can be an XML string, an XML document, or a relative path to an XML document. To figure out what it is, we make use of the GetXMLDoc function, which always returns an XML document. The code for GetXMLDoc is shown in Figure 10.
One of the hardest things about working with XSL is diagnosing whether problems are occurring in your XSL document or the source XML document. The two functions in Figure 11, which we borrowed from MSDN, will save you tons of time in the debugging cycle.
The combined use of all these functions leads us to the ever-so-useful TransformXML function, which is shown in Figure 12.
Now that weï¿½ve gone over the two approaches to produce the same table and looked at the helpful functions used to implement them, letï¿½s start talking about why the XML/XSL design is better. What is XSL doing for us? You provide it an XML document (the data), and it applies presentation rules to produce HTML. Isnï¿½t that what ASP does? Yesâ"but XSL does it better. Letï¿½s now look at those nine good reasons to use XML and XSL.
Separation of Presentation and Data Youï¿½ve probably read about separating the presentation layer code from the data for quite some time without really knowing how to achieve itâ"hey, youï¿½re not alone! ASP seemed to force the two layers together. But since it doesnï¿½t seem like a big problem while youï¿½re writing the code, it was acceptableâ"seeing there wasnï¿½t a better alternative. ASP+ promises a solution to this conundrum, but as of this writing the technology is still in prerelease form.
The real benefits of separation arenï¿½t immediately obvious until later in the development cycle. Letï¿½s say youï¿½ve already written the ASP code to display the table from Figure 3. Then the product manager comes along and says that the table is great, but could you add it to another part of the site? The product manager almost certainly has not written any ASP, so he wonï¿½t understand that this may not be easy because the code is not something that is easy to reuse in different pages in the site.
So you sigh, mumble a "yes," and begin the copy-and-paste operation. Or maybe youï¿½ll try to learn from the last time and turn your ASP table-generation code into a function. A couple of hours and a few hundred Response.Write statements later, you finally have a function that can be called from anywhere in your site. Is there a better way?
Consider the XML/XSL example shown earlier. If you want the same table to appear in another part of the site, simply call TransformXML from that point and presto, the table appears. This is the way it is supposed to happen. The development tools you use and the runtime environment your app runs in should be flexible enough to allow for future changes, yet modular enough to promote the easy reuse of existing code. XSL provides this flexibility by doing a better job of separating presentation and data, leading to a host of benefits, including reusability.
Reusability This is a really simple, straightforward pointâ"so weï¿½ll keep it that way. As you know, the only good way to reuse code is to have functions available for other developers to use. The harsh reality is that ASP does not currently provide a good mechanism to package presentation code into functions. This is largely because the number of formatting options you can formulate in DHTML is too great to pass as input parameters to functions.
Using the XSL approach, you can call TransformXML to create data-driven HTML presentation code. At the same time, this solution is not limited because XSL gives you complete control over every possible formatting option. It is also very extensible because you can use different XSL stylesheets in different parts of your site or different stylesheets for different users based on their individual profiles.
Extensibility XSL is a technology specifically devoted to transforming data (XML) into other XML-compliant documents (in this case, XML-compliant HTML). As a result, youï¿½re going to see code that is much cleaner and easier to maintain. And, of course, clean, maintainable code is the prerequisite for extensible code.
Letï¿½s take a look at the traditional ASP approach. If youï¿½ve ever had to implement a data view (a list of authors from the pubs database, for example) in multiple pages across your site, then you probably examined at least four ASP-based options: using a server-side include, using an ASP function, copying and pasting code, and writing a COM object (possibly using WebClasses). All of these approaches have some combination of the following problems, making the solutions difficult to extend:
A simpler approach would be to generate an XML document that contains the authors you wanted to show. Next, you could write one or more stylesheets that transform the XML into HTML. In the places where you wanted to show this view, simply call the TransformXML function shown in Figure 12.
- Code is mixed with HTML, making it difficult to maintain and having the potential to cause performance problems.
- If the copy and paste approach to code reuse is employed, changes and bug fixes have to be made in multiple places, creating a source-control nightmare.
- Code is unnecessarily complex for the feature or code has to be recompiled to make simple formatting changes.
- A zillion Response.Write statements are used.
- Itï¿½s difficult to allow different formatting options by passing parameters.
The great thing about this approach is that you can create as many XSL documents as you want, allowing programmatic selection (or even user selection) of the type of view you want to show. For instance, if certain users are required to maintain author information, you could create an XSL stylesheet for them with updateable fields. Other users might get a read-only view, while users with special visual requirements might need a larger typeface. Last, browser-centric views could be created for other Internet devices like WebTVÂ®, Windows CE-based devices, or wireless handsets. In this scenario you are only limited by the number of stylesheets you need or want to write. And once you have a variety of views, you can get access to them through a single line of code, freeing you to use the view wherever you want in your application.
Unfortunately, the only tool ASP provides to make your life easier is Response.Writeâ"not much of an option. XSL, on the other hand, was built with presentation flexibility in mind. It provides a host of features that make developing presentation layer code easy. While it is not our intention to review XSL in this article, a brief outline of these presentation-specific features is in order. These features include:
Division of Labor
One of the main benefits of the three-tier model is the opportunity to divide development tasks among developers who have different skills. For instance, with a clear demarcation between the data tier and the middle tier, only the data-tier team needs to worry about the complexities of the relational data model.
One of the gaps in the three-tier model (at least from our perspective) is that there can hardly be good separation when middle-tier developers (and in most cases presentation-tier developers) are working with recordsets. There is something fundamentally wrong with your data isolation strategy when the presentation-tier developer is looping through recordsets. The XML-based approach allows development teams to be segmented along three-tier lines.
At the data tier, relational data is transformed into XML documents. At the middle tier, business rules are executed, selecting the correct XSL stylesheet to use based on the current userï¿½s access rights and profile. The middle-tier developers make the call to TransformXML to execute the presentation code. At the presentation tier, the developers and designers work with one or more XSL stylesheets to ensure that the design guidelines for each stylesheet are consistent with each other and the rest of the site.
While itï¿½s possible to create this type of a division in ASP-based applications, it is much more difficult. This results from a number of limitations, notably that recordsets canï¿½t represent hierarchical data and that itï¿½s difficult to write, maintain, and extend ASP functions that generate HTML.
Simplified Data Model Most n-tier applications have some kind of data that is normally stored in a relational database. While this technology is at the heart of all business systems, its fundamental limitation is that the data is spread across multiple tables. This inevitably means spending a great deal of effort determining the correct normalized structure for the database and writing all of the data access code that maintains foreign key relationships. If a new requirement arises and the schema is changed to accommodate a new field, the data access code must change to accommodate reading and writing the values for that field.
All of that effort pays off when it comes time to query or analyze the data. Sophisticated query engines return lighting-fast results. But what happens when you donï¿½t actually perform complex queries? What if you only want to read and write an entire transaction at a time? Does it still make sense to write the data access code and maintain foreign keys?
In our last two articles (see http://www.microsoft.com/mind/0100/vml/vml.asp and http://msdn.microsoft.com/msdnmag/issues/0300/vml2/vml2.asp), we said that you should only go to the effort of storing data relationally if you need to, and weï¿½re saying it again now. Instead of a relational database, use XML to store hierarchical data, then store the resulting string in your database. If you need to do queries on the data, extract key fields from the XML and store them alongside. This ties directly into the next reason to use the XML/XSL approachâ"storing the entire transaction as one XML document in your database.
One Transaction, One Place In the first XML-based system that we started work on in 1998, about halfway through the development cycle we realized something really exciting was happening, and it was largely by accident. The development teams in all three tiers were finding themselves unchained from the restrictions of traditional relational models because they had simple and complete access to an entire transaction in a single, easily transferred string. Only the data-tier team had to deal with all the nuances of the large relational model.
Letï¿½s take the common example of a purchase order that has two addresses: a shipping address and a billing address. Also included in this order are 26 products, the number of units, price, and tax information. This type of largely hierarchical information simply cannot be represented in a simple recordset, and therefore cannot be transferred as a single unit. In this model, developers at each tier frequently donï¿½t have access to the information they need and spend a great deal of time coercing data from the data tier. The result is that developers at all tiers write a great deal of plumbing code.
In the XML model, the purchase order can be represented as a single string that can be easily sent to all tiers in the system, even in a geographically distributed system using SMTP and/or Microsoft Message Queue Services (MSMQ), as discussed in the BizTalkâ¢ framework (see http://www.microsoft.com/biztalk). Finally, developers can use the XML Document Object Model (DOM) to reduce the amount of plumbing required to retrieve the data they want.
While our discovery wasnï¿½t as monumental as, say, penicillin (also discovered accidentally by a Scottish scientist), for us it was the beginning of a new style of application design, focused on the use of XML and XSL.
And for icing on the cake, the use of tools in the latest release of the BizTalk Jumpstart Kit (see http://www.microsoft.com/biztalk) can easily and automatically turn XML schemas into standard COM object models, making it even easier for developers to access the data. It doesnï¿½t seem like much, but if youï¿½ve ever had the pleasure of working on a system like this, youï¿½ll know what a difference it can make.
Simplified Testing The XML-based approach makes testing much easier. The reason is tied very closely to the concept of one transaction, one place. Testing of any sort (system testing, regression/unit testing, and performance testing) is not an easy taskâ"especially if you want to do it well. One of the main reasons is that in most systems it is very difficult to "save" a test case. Why? The dataâ"the userï¿½s state that got them where they are in the applicationâ"is spread across multiple tables and session variables.
In system testing in the XML-based model, the userï¿½s entire state (that is, the current state of their transaction) can be stored in a single XML document. Thus, the system testers simply save their state (using a link in the application that is only available during system test) and attach it to the test case. When the developer gets the assignment, they do the reverse (that is, click a link and load the XML into the application), at which point they have the exact scenario that system testers did when they encountered the problem in the first place. This saves a lot of time because the system tester doesnï¿½t have to describe in explicit detail the sequence of events (for example, I clicked login, entered Bob as user name, Judy as password, went in the My Profile section, and so on). And the developer doesnï¿½t have to reproduce all these steps on the other side.
Again, in regression/unit testing, because the state is stored in a single XML document, it is easy to save different test cases to disk, and then replay them at a later time when a code change has been made. In many cases this can lead to automated regression testing where the input XML stays the same (the test case) and the resulting XML is compared against previous working tests to check for differences.
For performance testing you can build up a library of test cases, and then play these test cases at an accelerated rate to test the system for performance problems.
XML isnï¿½t going to save the day when it comes to testing. Youï¿½ll still have to apply the iterative test/fix/release process and youï¿½ll have to design your system properly so that it is testable and testing is repeatable. However, an XML-based approach can really improve the process.
Another reason to embrace XML and XSL as an alternative to straight ASP development is the potential for smoother legacy integration. This is an idea weï¿½ve been promoting for a whileâ"our article, "Make Your Legacy Apps Work on the Internet," in the September 1999 issue of Microsoft Internet Developer reflects this concept.
While there is a great deal to say on the subject, weï¿½ll keep it short and say only this: it becomes much easier to integrate your Web applications in the future if they are XML-capable. Instead of delving into code each time you want to use an existing feature, you can submit an XML-compliant document to perform a particular operation. If you have an account lookup module, for example, you need only write it once. Other applicationsâ"some you havenï¿½t even dreamed of yetâ"will be able to hook into that service down the line.
Look to the Future There is little doubt that XML will have a profound impact on Internet application development. Just looking at the number of products that have been released recently and the number of companies using XML at the center of their enterprise should be convincing enough. Microsoftï¿½s XML parser has gone through a number of revisions and is now in beta. SQL Server 2000 provides native XML support. The BizTalk Framework uses XML extensively, as does the Simple Object Access Protocol (SOAP).
If thereï¿½s one thing weï¿½ve learned about XML, itï¿½s that once youï¿½ve found one reason to use it in your application, youï¿½ll find many more. XML will play an important role in application development in the future, so be prepared to take advantage of it now.
Conclusion ASP can be used for all three tiers, but it is not a technology dedicated to the transformation of data into presentation code. Hence, XML and XSL are a superior choice for several reasons. Weï¿½ve talked about nine reasons to start using XML right now, even in some of the simplest Internet applications.
The separation of data from presentation code allows you to divide development tasks and build reusable, extensible, and maintainable code. Since XML can store each transaction in a single place, youï¿½ll have the opportunity to accelerate testing, simplify data models, and integrate your new and future with existing legacy systems. Finally, youï¿½ll be preparing yourself for the explosion in XML-based technologies, services, and products that has only just begun.
So the next time youï¿½re faced with unending lines of ASP and you sit there wondering if there is a better way, remember, there is. Itï¿½s time to learn XML and XSL.