This article may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist. To maintain the flow of the article, we've left these URLs in the text, but disabled the links.


MIND

This article assumes you're familiar with HTML, CSS, JScript, XML
Download the code (7KB)
VML Provides XML-based Graphics for the Web
Scott Howlett and Jeff Dunmall

Vector Markup Language, new to Internet Explorer 5.0, lets you generate vector-based images on the fly using some simple XML.

Most Internet developers generally focus on technology advancements that are happening on the server—things like COM+ and queued components. But when we took our heads out of the sand, we realized that Microsoft® Internet Explorer 5.0 would be as important as Windows® 2000 in terms of its impact on Internet application development. This is primarily because Internet Explorer 5.0 shipped with improved support for Extensible Markup Language (XML) and two new XML-based offerings: Extensible Stylesheet Language (XSL) and Vector Markup Language (VML).
      In this article we'll introduce an XSL design pattern that is suited to developing Internet applications. Along the way, we'll show you the basics of VML. Finally, we'll introduce a sample application that produces a graphic representation of an organization chart on the fly.
      We'll not only make extensive use of VML, but also XML and XSL. This results in source data that is completely separate from any presentation code or processing. In a future article we will extend the organizational chart sample developed here to cover XSL pattern matching and support in Internet Explorer 5.0 for drag and drop operations. We'll also design a template for creating XSL documents that allows you to edit XML documents inside the browser. When we finish you'll have seen an end-to-end solution for managing organizational charts.

XML: Believe the Hype
      We're forever wary of technologies that are hyped—we learned our lesson most recently after jumping on the ASP bandwagon without reading the fine print about scalability and state management. XML definitely qualifies as a highly hyped technology, but we're convinced that it will have a profound impact on Internet application development.
      XML, as a data store, is the perfect complement to HTML. HTML is a text-based presentation markup language, which is why it earned widespread adoption in such a short period of time. Ironically, the text-based nature of HTML has also been one of its biggest limitations. Over the years, the HTML standard has been extended to address this limitation by adding support for both Dynamic HTML (DHTML) and scripting.
      Although the HTML standard was modified to allow for dynamic pages (via DHTML), one of the remaining limitations is that the source data is hopelessly intertwined with the presentation semantics: the HTML code. This makes it impossible for the client to manipulate the data directly, and introduces all sorts of needless data transformations. A side effect is that Web servers waste precious processing cycles formatting data into HTML—something that can now be easily pushed down to client machines.
      For example, have you ever looked at a relational data model and wondered why it's done like that? Why is every piece of data split off and stored in its own separate field? Consider the typical fields in a contact database: FirstName, LastName, HomePhone, MobilePhone, PagerPhone, EMail, and so on. Do words like "fully normalized" and difficult-to-learn client/server lessons spring to mind? Perhaps the technology now available to build Internet applications has shifted some of these fundamental assumptions. In the past we always split values like HomePhone and MobilePhone into separate fields because there was no other convenient way to do it. Is this still the best design?
      Think about what's going on. To execute an edit, the data is retrieved in an ActiveX® Data Objects (ADO) recordset and, using ASP, is "thunked" into an HTML form. ASP jumbles up the presentation markup tags with the data itself, making it difficult to do any client-side manipulations. The client then sends the changes back in an HTTP post. The data is thunked again, field-by-field, into a huge SQL string and put back into the database. If only we could regain the time spent concatenating strings to make valid SQL statements!
      A much simpler approach is to store the data in XML on both the server and the client. This has many advantages. The amount of data transformation code is reduced, but more importantly it allows the client to manipulate the data in its native format.

Figure 1: XML/XSL Design Pattern
      Figure 1: XML/XSL Design Pattern

      Using XSL, the results of changes can be shown to the user immediately without a round-trip to the server. The client can manipulate the data and display it as the user sees fit, while keeping the server out of the picture. The client now has the tools to quickly and efficiently manipulate an XML string. In the end, we have an alternative to data storage in a relational database. The new approach is shown in Figure 1.

Usage Case
      This design pattern applies when it makes sense to store the data in XML. The hard part is determining when this is the case. We suggest looking at two key factors. First, is the dataset built on the client? An example of this is an e-store. Typically, a user navigates the site adding items to her shopping basket. In this case, an XML document could be built on the client machine. Second, is the dataset small? Contact information for a single person is a small dataset and, therefore, would be represented efficiently in XML. However, it would not be practical to store millions of contacts in a single XML document.
      The best approach is to store small datasets in XML, which are then inserted in a text field of a relational database. Several fields should be extracted from the XML prior to insertion into the database and placed in separate columns for indexing and searching. Thus, for a contact, the data model may contain only two fields: LastName and the XML that represents all other fields.
      This approach takes advantage of both the capacity of traditional databases like Microsoft SQL Server and the potential for Internet applications built on XML. In a future article we will introduce XSL pattern matching, which gives yet another option for filtering data. Pattern matching can be performed on the client, so another round-trip to the server can be eliminated.
      The general consensus is that a page of HTML generated by ASP is a well-implemented presentation tier. This is true if the data is static, but not if the site is interactive. The problem with this approach is that the data is embedded in the presentation code and the client cannot manipulate it directly. The data will be represented in several forms: in one form on the server, in another on the client, and possibly another during the transmission between server and client. The result is a mass of code that performs data transformations.
      Using XML and XSL, Web developers can push much of the presentation processing to the client, freeing Web servers to do more advanced processing. With Internet Explorer 5.0, Web developers are able to use a design pattern that is much better than what they've traditionally used.

Vector Markup Language
      Simply put, VML is an XML language schema used to describe and format vectors. At this time, a draft specification for VML has been submitted to the W3C. (You can find it at http://www.w3.org/TR/NOTE-VML.html.)
      VML was designed to help developers address problems with binary graphic files (GIFs, JPGs, and so on). These limitations of binary graphic files include:

  • Their large file size causes them to download slowly, especially over slow links
  • They're difficult to maintain and change
  • They're external to the rest of the HTML document, making them difficult to distribute
Figure 2: VML Square
      Figure 2: VML Square
      Internet Explorer 5.0 includes the first release of VML, and is currently the only browser that supports VML. Using VML, you can mark up vectors and polygons and Internet Explorer 5.0 will draw them on the screen. For example, you can draw a blue square like the one shown in Figure 2 by including the following VML in your HTML document:

<v:rect style="width:50pt; height: 50pt" fillcolor="blue" />
The full source is shown in Figure 3.
      VML is fully supported by Office 2000. This means that you can use Microsoft Excel, Word, and PowerPoint® to create pictures, then save the document in VML by default, along with a GIF or JPEG image. To make VML the only saved format, you have to make a simple change in your options. In Word, for example, go to Tools | Options, select the General tab, and click the Web Options button. The Pictures tab lets you check the "Rely on VML for displaying graphics in browsers" option.
Figure 4: VML & Office 2000
      Figure 4: VML & Office 2000
      The graphic shown in Figure 4 was generated in Microsoft Word. If you save the file as a Web page in Word, the resulting HTML file is about 6KB of HTML and VML. Try generating your own HTML file if you're curious, or download the source code from the link at the top of this article. There is no external GIF or other binary graphic file to deal with; the image is generated using nothing but VML.
Figure 5: Simple Changes
      Figure 5: Simple Changes
      If you're not yet convinced of the power of VML, consider this: the graphic in Figure 5 was generated from the same HTML file as the one that created Figure 4. We simply searched for "VML" in the source document and replaced it with "MIND".
      A great application of VML is the creation of menus and navigational elements. You could use VML to create a graphic that would serve as the background for the image. Using XSL, you could then create the menu, dynamically inserting whatever menu text you want.

Nuts and Bolts
      Let's examine the source code in Figure 3 to understand how VML works in Internet Explorer 5.0. There's a lot going on here, even in this simple example. There are two things of note: the VML namespace and the VML behavior.
      The first line identifies the VML namespace:


 <html xmlns:v="urn:schemas-microsoft-com:vml">
This code tells Internet Explorer that all tags beginning with v: are part of the VML namespace, as opposed to the default HTML namespace.
      The second item you should examine is the declaration of the VML behavior:

 v\:* { behavior: url(#default#VML); }
This instructs the browser to pass all of the tags beginning with v: to the rendering object. If you omit either of these aspects of the document—declaring the namespace or declaring the behavior—the VML will not be displayed. If you are having trouble producing VML output, start your debugging by looking for these elements.

VML Semantics
      A quick reference document for VML can be found at http://msdn.microsoft.com/standards/vml. The W3C document referenced earlier is extremely detailed, talking about limo-stretch points and scaling anisotropically. But before you run to the dictionary to look up "anisotropically" (we still don't know what it means), let us give you a quick overview of VML.
      The first thing to note about VML is that is uses the existing mechanisms of HTML and Cascading Style Sheets (CSS). Therefore, all top-level VML tags support the style attribute in the same manner that all HTML elements support it. You'll see later that to render text inside a VML object (using the <v:textbox> element), you'll use HTML.
      The main VML tag is <v:shape>. This tag defines a generic shape element, which does not have any form. <v:shape> merely defines the containing rectangle in which the graphic will be drawn. The shape element has a style attribute where you can specify the size and location of the element. For example, the following code creates a shape element that is 100 millimeters square:


 <v:shape style="top: 0; left: 0; width: 100mm; height: 100mm;"
 coordsize="3 3" />
The coordsize attribute lets you redefine the coordinate space into appropriate units. In this case, it specifies that the square is spanned by four units (0 through 3) on the x and y axes.
      But this only defines the containing box of the shape. To define the shape itself, use the <v:path> element. The path element has an attribute, v, that defines the points to draw. You set v to a string that represents a list of vector-based drawing operations. The points are x,y values in the units of the coordsize attribute of the parent shape element. As part of the v attribute, you can use the letters m for moveto and l for lineto. The x attribute will close the path by joining the current point to the first point in the path, while e simply ends the current path.
      The <v:shapetype> element is used to predefine a shape that will be used elsewhere in the document. You must specify an ID attribute because this is how the <v:shapetype> is referenced elsewhere in the document. Usually a <v:shapetype> is used when more than one of the same shape is to be used in the document. This element does not produce any visible output. Instead, the syntax <v:shape type="#id"> is used. The following code defines an octagon that can be used repeatedly throughout the document.

 <v:shapetype id="octagon" coordsize="3 3" >
     <v:path v="m 1,0 l 2,0,3,1,3,2,2,3,1,3,0,2,0,1 x e"
 textboxrect="0,1,3,2" />
 </v:shapetype>
Figure 6: Shapes
      Figure 6: Shapes

      The <v:textbox> element lets you display text inside a VML object. It allows rich HTML to be inserted, building on the existing features of HTML and CSS. This VML code draws the graphic shown in Figure 6, making use of the octagon shape type:

 <v:shape type="#octagon" style="width: 1in; height: 1in;"
 fillcolor="red">
 <v:textbox style="text-align:center; font-weight:bold">
 Stop</v:textbox>
 </v:shape><br/>
 <v:shape type="#octagon" style="width: 1in; height: 1in;"
 fillcolor="yellow">
     <v:textbox style="text-align:center; font-weight:bold">
 Caution</v:textbox>
 </v:shape><br/>
 <v:shape type="#octagon" style="width: 1in; height: 1in;"
 fillcolor="green">
     <v:textbox style="text-align:center; font-weight:bold">
 GO</v:textbox>
 </v:shape>
      In addition to these elements, there are also <v:line>, <v:polyline>, <v:roundrect>, <v:oval>, <v:curve>, and <v:arc> elements that make drawing simple shapes easier than using the <v:shape> and <v:path> combination. The details of the additional VML elements, of which there are many, are beyond the scope of this article.

Sample Application
      Now that you've seen the basics of VML, let's jump into a sample application that's a little more interesting. To demonstrate the design pattern, we'll take raw XML and send it down to the client, where it can be shown and manipulated in a variety of forms.
      Let's say you own a consulting company. As a prudent businessperson, you should record everything you know about your clients; after all, this information is one of your company's primary assets. You're particularly interested in gathering information about your clients' organizational structures, so that you can make sure your sales team is targeting the right people.
      We'll start by building a typical HTML-based intranet site that presents information about each of your clients. The first step is to determine how the data is going to be stored. XML is hierarchical, and despite what they tell us, so is the organizational structure at most companies. So storing the information in XML is going to save lots of time compared to building a hierarchical model in a traditional relation database—can you imagine the foreign key nightmares? The XML documents used will look like this:


 <CLIENT>
     <COMPANYNAME/>
     <PEOPLE>
         <PERSON>
             <NAME/>
             <TITLE/>
         </PERSON>
         <PEOPLE>
             <PERSON/>
             <PERSON/>
         </PEOPLE>
     </PEOPLE>
 </CLIENT>
      The next step is to take the XML and transform it into HTML. There are many ways to do this, but the best way is to use XSL. XSL provides a simple yet powerful model for the transformation of one XML document to another. In this case, we're going to transform a client XML document into an XML-compliant HTML document.
      This is one of the tricks of XSL: the resulting document must be valid XML. Whereas you're probably used to using <BR> to start a new line, with XSL you must use <BR/> to keep the document valid. Dino Esposito's Cutting Edge columns in the June, July, and August 1999 issues of MIND describe the basics of XSL.
      To start, we can use XSL to generate HTML code that provides a textual representation of the organization. This is a good starting point as the XSL will be straightforward and the resulting application will be simple and effective. This is the typical approach you may have read about in other articles. The XSL could be applied on the server to handle noncompliant browsers, or sent down to the client to reduce server-side load. Browser-specific XSL could be applied, depending on the target, as Dino demonstrated in the Cutting Edge columns just mentioned. The resulting page would look something like Figure 7.
Figure 7: A Text-based Representation
      Figure 7: A Text-based Representation

      The most common approach to rendering the text-based representation in Figure 7 would involve pointing the browser directly to a source XML document that references a style sheet. To do this, you would place the following line at the top of your XML document:

 <?xml:stylesheet type="text/xsl" href="myxsl.xsl"?>
      By doing this, Internet Explorer will load both the source XML and XSL documents and do the transformation for you. The document resulting from the transformation has to be a valid HTML document in addition to a valid XML document. This means that your XSL document has to contain all the appropriate tags to create a valid HTML document (<HTML>, <HEAD>, <BODY>, and so on). This approach, while good for debugging purposes, is limited for a number of reasons. It clutters your XSL, makes it impossible to use multiple style sheets in the same HTML document, and assumes the source is the XML data itself. While this is a common approach, there is a more flexible solution.

A Container Document
      Instead of the approach just outlined, we used two XSL documents and one container document. It's better to use a container document that has the standard HTML tags and then transform the XML programmatically when the window loads. Think of the container as the skeleton template for the page, which has a variable number of placeholders for additional information, depending on user preference. This allows multiple transformations on the same page, so it's possible to present different views of the same XML data. Users will appreciate this because it allows them to use the view they prefer.
Figure 8: The Client Box
      Figure 8: The Client Box
      If you take a closer look at the Client box in Figure 8, you can see the difference. Two separate XSL files do the processing to create View 1 and View 2. The source XML stays constant, stored in an XML data island in the client document.
      This solution also has great caching benefits. The XSL files get downloaded once and stay on the client. Each time the page is hit, the skeleton container page comes down with the dynamic data.
      To do the transformation programmatically on the client, there are three steps:

  1. Create two XMLDOM objects and set their async properties to false.
  2. Load the source XML document and the source XSL document.
  3. Transform the source XML document and write the results to the HTML document.
      These steps are executed in the code shown in Figure 9. This code assumes that there are two DIV elements named header and companyinfo in the HTML document, where the results of the transformation will be placed. These are represented by View 1 and View 2 in Figure 8.
      The first transformation uses header.xsl to create the page header. It displays the company name and places a horizontal rule below it. The second transformation displays the company structure, using indentation to depict the hierarchy. This approach is more flexible because other transformations can be used to display the company structure, like using VML to represent the organization. More generally, you can change the look and feel of one portion of your site by changing a specific XSL document.

XSL for VML
      Finally, we'll do a third transformation that produces VML output. The first thing to do is produce the XSL that renders a standard organizational chart. We decided to use HTML tables to help with the layout of the chart. It was simple and handled varying screen sizes and resolutions nicely.
      XSL is great because it lets you do recursive and iterative operations easily. This example is iterative because there are multiple <PERSON> tags in the <PEOPLE> element. The recursion comes into play because <PEOPLE> contains <PERSON>, and vice versa. For this implementation, each <PEOPLE> collection will be in its own table and each <PERSON> will be in its own cell. First we apply the people template with the following line of XSL:


  <xsl:apply-templates select="CLIENT/PEOPLE" />
      Inside the people template, we create the HTML table and a row in the table, and then apply the person template for each <PERSON> in the <PEOPLE> collection:

 <xsl:template match="PEOPLE">
     <TABLE border="0" style="display: block">
     <TR>
     <xsl:apply-templates select="PERSON" />
     </TR>
     </TABLE>
 </xsl:template>
      In the person template, we create a new cell and then a round rectangle with the name and title of the person, using the <v:roundrect>, <v:fill>, and <v:textbox> VML elements. Next, we apply the people template shown in Figure 10, which introduces the recursive nature of this example. The result is shown in Figure 11.
Figure 11: An Organizational Chart Using XSL
      Figure 11: An Organizational Chart Using XSL

      But we weren't happy with this. For large organizational charts, the picture was too big to fit on the screen, and we wanted to be able to focus in on a particular group by collapsing the branches we weren't interested in. To accomplish this, we first had to identify which persons had subordinates. Next, we wanted to provide a visual cue to the user about which nodes could and couldn't be clicked. Finally, we wanted to change the mouse cursor to a hand on a mouseover for persons that had subordinates. Once we had that figured out, all that was left was to write some code to show and hide different branches.
      Determining which person nodes had children was made easy by using a conditional test statement in XSL. The XSL code to adjust the mouse cursor looks like this:

 <xsl:when test="PEOPLE/PERSON">
 <xsl:attribute name="style" >width: 110pt; height: 33pt; cursor: hand
 </xsl:attribute>
 </xsl:when>
 <xsl:otherwise>
 <xsl:attribute name= "style">width: 110pt; height:33pt; cursor: default
 </xsl:attribute>
 </xsl:otherwise> 
      We did the conditional test using "PEOPLE/PERSON" because this would only apply the conditional formatting if there was a child <PEOPLE> collection that contained at least one <PERSON>. Similar XSL code is used to place a shadow on the persons with subordinates, giving the user good visual cues. The script to show and hide the different branches is relatively straightforward (see Figure 12).
      The end result displaying both XSL transformations is shown in Figure 13. Note that Bill Onliane has been clicked to roll up his subordinates.
Figure 13: Full-featured Organizational Chart
      Figure 13: Full-featured Organizational Chart

      There's some complex pattern matching in this example which we don't discuss in detail here. A future article will discuss XSL pattern matching in more detail.

Going it Alone
      Looking back to the days when ASP was first introduced, we thought we'd never again work on a platform where the development environment was so sketchy, but here we are again. Developing XSL is a difficult task, and the learning curve is steep. Generally speaking, it's back to Notepad. Right now there is no built-in support for XSL in Visual InterDev® 6.0 or FrontPage® 2000. There is also no support for VML, and debugging help is limited.
      If, for example, the XSL document is not valid XML, no error will be produced; all you'll see is a blank white screen. There is some great error detecting code on MSDN that can help solve this problem (http://msdn.microsoft.com/xml/xslguide/transform-errors.asp). We highly recommend including the error detecting and handling code provided in this sample. Another alternative is to load the XSL document into Internet Explorer first; it will reveal any XML syntax problems. If the document produced by the XSL transformation is not itself valid XML, you'll also get the blank white screen.

Conclusion
      The combination of XML and XSL provides the mechanism to modify traditional n-tier design concepts, pushing presentation processing back to the client. In addition, these technologies provide the opportunity to simplify database design using an embedded XML store and at the same time give the client access to source data—data that is not intertwined with HTML.
      By transforming XML programmatically, the developer is able to present one or more views of the same data using one or more style sheets. This allows the user to choose which view is best suited for the task. In addition, VML allows Web developers to steer away from traditional site design because it enables graphics to be generated on the fly.
      Who would have thought 25 lines of code could generate a graphical view of an organizational chart? As you can see, the combination of four Web technologies (HTML, XML, XSL, and VML) allows for rich content to be generated with very little code. We know this doesn't have all the glamour of the new event model in COM+, but if you drop these technologies into your toolbox, you won't be disappointed.

MSDN
Vector Markup Language (VML) Overview at:
http://msdn.microsoft.com/standards/vml/default.asp

From the January 2000 issue of Microsoft Internet Developer.