Export (0) Print
Expand All

Online Carpentry: Refinishing Your Table of Contents

As of December 2011, this topic has been archived. As a result, it is no longer actively maintained. For more information, see Archived Content. For information, recommendations, and guidance regarding the current version of Internet Explorer, see IE Developer Center.

Bryn Waibel and Stuart Updegrave
Microsoft Corporation

December 21, 2000

Download Toccode.exe.


Java, HTML Help, Web Technologies
Questions and Answers

In July, we published Online Carpentry: Crafting a New MSDN Table of Contents, where we looked at how the MSDN development team designed and built the new MSDN TOC. Since then, we've had a lot of feedback, and we've made a few changes to the TOC. In this article, we'll go into some of the most useful of the comments we received. We'll look at our rationale for doing what we did, and we'll show where we've made some changes. We'll also give you an outline of the TOC requirements.

Decisions: Java, HTML Help, Web Technologies

Several readers wanted to know why we decided to replace our existing implementation and how we made certain design decisions. The cynical perspective is that we replaced the previous version of the TOC because it was implemented in Java. To some extent, that's actually true: Many firewalls exclude Java for security reasons, which means that the MSDN Library was historically very difficult to navigate in corporate environments. Additionally, the applet never worked right on the Macintosh (which admittedly has only a small representation among MSDN Online's user base, as indicated by server logs). These two reasons were paramount in our decision to replace the existing implementation.

One of our readers questioned why we didn't use HTML Help as our new TOC rendering engine. There are several reasons for this: First, implementing a TOC on top of HTML Help would require the use of a client-side ActiveX control. This would effectively block all users who are not using Internet Explorer 3.0 or later on a Windows platform. Second, we are a team of Web developers—we wanted to replace the limited-scope version by using common Web technologies, including ASP, XML, JScript, and CSS. This technology provides the additional benefit of dramatically increasing the potential user base, since fewer firewalls exclude client-side script. The user base also expanded because we were able to branch implementations to better support clients that don't support Internet Explorer's flavor of DHTML.


We omitted a requirements section in the first Online Carpentry article. We'll give the requirements under a variety of scenarios, and we'll explain how to work around some of the more expensive options.

XML 2.0

You have a couple of options for XML 2.0. You either need to install Internet Explorer 5.0 or 5.5, or you need to download the redistributable bits of MSXML 2.5 Service Pack 1 The XSL shipped with the sample is not designed to work with versions of MSXML later than 2.5, but you can make it work. The XSL namespace declaration needs to change, meaning that the following declaration:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">

needs to refer to the newer XSLT namespace definition, like this:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" 
<xsl:output omit-xml-declaration="yes" standalone="no" 

A second problem with trying to use the sample code with newer parsers is that the sample map.xml file uses a DTD to specify that the "url" attribute is an ID. MSXML has dropped DTD support in favor of an extensible data description language called XML Data Reduced (XDR) Schema Language. This simply means that you can't use a DTD to describe your XML anymore, so you need an XDR Schema, which would look something like this:

    <Schema name="map" xmlns="urn:schemas-microsoft-com:xml-
       <AttributeType name="url" dt:type="id" />
       <AttributeType name="url" dt:type="string" />
       <ElementType name="L" model="closed" content="empty">
            <attribute type="url"/>
            <attribute type="pth"/>
    <L url="somefile"  pth="somepath" /></MsdnTocMap>

Now all you have to do is install the MSXML 3.0 Parser and replace all of the PROGIDs in the sample ("Microsoft.XMLDOM") with "MSXML2.DOMDocument" and you're ready to go.

IIS 5.0

Internet Information Services (IIS) 5.0 is required in order to support UTF-8 codepage 65001 content on the server. If you don't need an extended character set (and you probably don't unless you want to display multiple languages in a single UI engine), you can simply change the code page of each .asp file to the appropriate code page for your TOC.

MSDN Magazine also has an interesting article about globalization, Michael Kaplan's Go Global: Designing Your ASP-based Web Site to Support Globalization. If you do need extended character support, Kaplan offers an interesting workaround for this problem.

Microsoft JScript 5.0 or later

If you don't have a version of the JScript engine that supports try-catch blocks, you may find that you get an error like this when you try to run the sample:

"Microsoft JScript compilation error '800a03ea' , Syntax 
error , /toc.asp, line 8 , try ^" 

While initially this error can seem debilitating, it isn't too difficult to work around. Of course, the recommended solution is to install the newest version of the http://msdn2.microsoft.com/en-us/library/ms950396.aspxScripting Runtime. If that's not an option and you have an older version of JScript, you need to remove the error handling. Let's say a script block looks something like this:

try  //remove this
{  //remove this
   // processing code here
} //remove this
catch(e) //remove this
{ //remove this
      // error handling here // remove this
} //remove this

To make sure that the code works with any version of the Jscript scripting engine, remove every line with the "//remove this" comment.

Questions and Answers

Q. I want to understand the structure of the TOC. The example uses a single directory for everything (it is flat), while a real-life situation would make use of a structure. I am not sure what files need to go where in this structure and how many different versions of each file type are needed. Must absolute paths be coded into the scripts and data files?

A. The TOC that we shipped with the first Online Carpentry article was meant to be self-extracting. We used a flat directory structure so that you could just drop the .exe into any directory on your Web server and let it go. We realize that though that makes good sense for distributing a sample, it doesn't give too many hints about which architecture would be workable in a real-world situation.

The TOC sample raises one question in particular: What exactly is the use of locals.inc supposed to accomplish? The answer is simple: We collapsed the structure, so the .asp pages in the sample should really be a combination of two include files:


<% @codepage="65001"  @LANGUAGE="JScript" %>
<!-- #include file="locals.inc" -->
<!-- #include file="/shared/inc/toc.inc" -->

The same would apply for loadtree.asp:
<% @codepage="65001"  @LANGUAGE="JScript" %>
<!-- #include file="locals.inc" -->
<!-- #include file="/shared/inc/loadtree.inc" -->

This allows the code that runs the TOC to be completely shared and reusable across an entire Web site. All of the information that is local to a single implementation on that Web site can then be stored in the locals.inc file.

A second problem with the flat directory structure is that it doesn't do a good job of explaining the exact role of the map files. Imagine that the files that came with the sample were stored in a folder structure that is not flat: the include files (.inc, .asp) would be stored in the "/sample/inc/" folder, the .js files in the "/sample/js/" folder, and so on. It's easy to imagine what the ltoc0.xml file would look like. The ref attribute would have the full root-relative path stored in it:


So where do the map files go? A map file must be in every folder in which there is a file that is referenced in the TOC. That is the only way we can distribute the load of thousands and thousands of files across the file system; we wouldn't want to represent all 300,000 MSDN Library nodes in one file.

The TOC files (ltoc0.xml and msdnce.xml) can go anywhere you want to put them. The only requirement is that prePartum attributes point to the right place, and that locals.inc knows where the first XML file is located. At MSDN, we like to place our TOC files in the TOC directory, right under the application.

Q. How do we set the TOC to display the first two or three levels of the tree by default, rather than just the top level?

A. If you want any node in the tree to display open by default, you need to set the state attribute in the corresponding .xml file to "open". For instance, for the sample code given, if you want to display "MSDN Code Examples" open when the page loads, you would write the XML like this:

       <MTN    title="MSDN Code Examples" 
            hal="en-us" state="open">
              <MTN    title="The MSDN TOC" 

We've updated the code sample in the MSDN Code Center to reflect this change.

Q. The first Online Carpentry article says, "The version in the attached sample runs the TOC only in Internet Explorer versions 4.0 and later." How do we support Netscape as well?

A. Actually, there's not much about the TOC that doesn't work in Netscape. We just didn't include the .css file. The TOC should be completely functional in Netscape, but most likely will not be very pretty. If you'd like the .css file that we use for Netscape, you can find it at http://msdn.microsoft.com/msdn-online/shared/xmltoc/css/toc_nav.css . You'll need to implement a browser sniffer and add a link to this file in toc.asp in the sample.

Q. With my table of contents, clicking the TOC shows the correct document in the topic frame, but I can't sync from the topic frame to the TOC frame; it just shows the top node. Here's the situation:

Both XML files are in the main directory ( = virtual FTPROOT dir ); so are the ASP files default and toc. The file in the topic frame is ftproot\Software\Cpp\Dependency Tracking.htm.

Extract from ltoc0.xml:

MTN title="Dependency Tracking.htm" nodeType="leaf" 
type="file" ref="\ftproot\Software\Cpp\Dependency 
Tracking.htm" tocPath="ltoc0-16-1-0"

Extract from map.xml:

url="Dependency Tracking.htm" pth="ltoc0-16-1-0"

I try to sync by calling toc.asp: http://-myweb-/ftproot/toc.asp?url=/ftproot/software/cpp/Dependency Tracking.htm.

A. This is a mistake on our part. Cleaning and simplifying the code to get it to work with the sample, we accidentally cut a crucial piece, and that causes this error. URLs can't have certain special characters in them without being escaped. In this case, for instance, the space in the URL needs to be escaped with %20. Here's the function that was accidentally cut. The updated sample has this function in place.

function FormatFileName( sFileName )
    sFileName = unescape( sFileName );
    sFileName = sFileName.replace( /[^\w\.-_:\[\]]/gi , "" );
    if ( sFileName.match( /^[\.\d]/i ) ) sFileName = "f" + 
    return sFileName;

Q. I want to create an easy way to manage a hierarchical list, which is more or less stored in SQL Server. I have a component to assemble the list and then return the XML as a string (rather than having a hard-coded file such as ltoc0.xml). Once the user clicks an item in the tree, I would like to display an ASP page that gives the properties of the selected item. To do this, I want to pass an "itemid" field in the query string and need to pass some other parameters (such as mode). I'm trying to use the "ref" tag inside the XML definition as an anchor such as "a href=filename.asp?ItemID=xxx&mode=view". For some reason it will only accept one parameter. If I just pass in the ItemID, it works fine. By adding the "&Mode=VIEW" portion, however, the tree doesn't even display on the page.

A. We faced this problem when we were getting the TOC to work with the MSDN Code Center. We handled it by encoding the ampersand in the URL and then decoding it on the client in the end. A quick and easy solution to this problem is included with MSXML 3.0, which allows you to specify encoding level within your transformation. As we stated earlier, you'll have to make a few modifications to get this to work with the newer parser. In that case, you would be able to encode the ampersand as &amp; in the ref attribute, then put the correct value into the resulting XML, using the following in your stylesheet:

<xsl:value-of disable-output-encoding="yes" select="@ref" /> 

Q. Why do some of the entries in the sample map.xml contain an extra .txt extension? Since the file names do not have the .txt extension on them, why are they defined that way in the map.xml file? Even in the ltoc0.xml file, the nodes that reference these files do not have the .txt extension.

A. We wanted to allow developers to see the source code rather than running an ASP, .css, or .js file and getting nothing. Adding the .txt extension, in effect, changes the content type so that the contents of the file can be displayed without the server or the browser trying to do what they do best with the code, such as parse it.

Q. Why not draw the lines in the Tree View?

A. We could have, and there are many ways to do it. In this case, it was just a decision on our end not to include the lines. The easiest way to do this, of course, is to change the folder images into images that include lines. You'd have to tweak the .css and add a background image to <UL> tags that would connect the lines, but it should work just fine.

Q. How do we support Chinese?

A. Look at http://msdn2.microsoft.com/zh-cn/library/default.aspx. You need to author your XML in UTF-8 on a Chinese system. If you're authoring on Windows 2000, install the Chinese font and locale pack.

Bryn Waibel is a senior Web developer at Microsoft. He is currently working on creating the architecture for the next generation of MSDN, TechNet, and Business sites.

Stuart Updegrave is a development manager at Microsoft, overseeing development of the MSDN, TechNet and Business Web sites.

© 2014 Microsoft