Displaying XML in Internet Explorer
by John E. Simpson
October 25, 2000
Q: How can I view XML using Internet Explorer 5.0? When I try,
only the tags are visible but not the contents. I've written an XSLT
stylesheet also, but it is not working.
A: (Laughing) Yeah, that's always a problem with all these
darned languages: They insist on being understood.
Before considering some ideas to unravel your confusion, you need
to understand one very important thing about Internet Explorer
5.0. The "XSL processor" built into it is not compliant with
the final XSLT
Recommendation. To bring it up to speed, you need to install the
very latest of a series of so-called preview releases of a component,
msxml.dll, available from the Microsoft site at
http://msdn.microsoft.com/xml/general/msxmlprev.asp. By common
consensus on the XSL-List mailing list, the very best source of
information on how to install this correctly is Joshua Allen's Unofficial
MSXML XSLT FAQ .
Once you've taken care of these preliminaries, you can follow along
with the answer to your question. I don't know what your XML looks
like, of course. But let's say you've got a document that looks like
this:
<?xml version="1.0"?>
<family>
<grandparent gender="male">
<persname>Morris</persname>
<parent gender="female">
<name>Betty</name>
<child gender="male">
<persname>John</persname>
</child>
<child gender="female">
<persname>Connie</persname>
</child>
<child gender="female">
<persname>Cindy</persname>
</child>
<child gender="male">
<persname>Mike</persname>
</child>
</parent>
</grandparent>
</family>
The general idea is that it repressents a bloodline descending
through three generations, from a grandparent, through his daughter,
to her four children. If you look at this with Internet Explorer 5+,
you see a collapsible/expandable tree of markup and content. Click on
a minus sign to collapse that branch of the tree, at which point the
minus turns into a plus. Click on a plus to expand the tree. This
quasi-interactive view of the document isn't built into XML; it's the
result of a stylesheet built into IE5+ -- specifically, the
aforementioned msxml.dll component. (To see the stylesheet, enter this
URL into IE's "Address" field: res//msxml.dll/defaultss.xsl.)
Remember, though, that this default stylesheet isn't XSLT. To
construct a simple stylesheet written in genuine XSLT, read on.
This will supply you only with the XSLT basics. For a
comprehensive, easy-to-follow tutorial, read Bob DuCharme's ongoing series,
"Transforming XML," here on xml.com.
An XSLT stylesheet is itself an XML document. Among its elements
and attributes are those that represent XSLT instructions for how to
transform the source XML into some result, which -- in the case of
IE5+, especially -- will typically be well-formed HTML.
The root element of an XSLT stylesheet is called xsl:stylesheet. A
bare-bones version of this element looks like the following.
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/TR/REC-html40">
</xsl:stylesheet>
The version attribute says that this stylesheet conforms to
version 1.0 of the XSLT standard. The two attributes whose names begin
with "xmlns" are namespace declarations. The first one, xmlns:xsl,
tells the XSLT processor that any elements whose names begin with the
prefix "xsl:" (including the colon, like the xsl:stylesheet element
itself) are XSLT elements. The second, xmlns, declares that any
elements whose names do not begin with a prefix will be HTML 4.0
elements. This is what we want here because with IE you generally want
to display a Web page. In effect, the stylesheet will convert all XML
code to HTML.
Let's say you want to apply this bare-bones stylesheet to your
document. You've got one more step, which is to add a processing
instruction (PI) to your document. This PI will tell IE what kind of
stylesheet you're using, CSS or XSLT, and where to find it. Let's say
the stylesheet is called family.xsl, and it's in the same directory as
the document itself. The document with this PI looks like this:
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="family.xsl"?>
<family>
<grandparent gender="male">
[etc.]
Now when you open the document, you won't see any tags
at all, only content. It will look like
MorrisBettyJohnConnieCindyMike
This is the opposite of the problem you've described in your
question, and probably doesn't seem like much progress at all. What's
going on here is that the XSLT standard prescribes a series of
built-in rules for how to transform the source document. According to
these built-in rules, for example, an element's content is displayed,
but attribute values are not. So what you're seeing is the content of
all the elements displayed contiguously.
To specify specific processing for specific elements, you add a
series of template rules to your stylesheet. Each template rule tells
the XSLT processor to which portion of the source document the rule
applies and provides a template (hence the term "template rule") for
what to create in the "result tree" (a corresponding portion of an
HTML document in this case).
We're going to use two simple template rules to create an HTML
table from our source document. The table will consist of three
columns: one for the relationship (grandparent, parent, or child), one
for the name of the person who has that relationship, and one for that
person's gender. The first template rule:
<xsl:template match="/family">
<table border="1" summary="Family tree">
<tr>
<th>Relationship</th>
<th>Name</th>
<th>Gender</th>
</tr>
<xsl:apply-templates select="grandparent"/>
</table>
</xsl:template>
Reading down through the template rule, it says
- This template rule applies to the root "family" element
only
- When you find such an element, construct an HTML table.
- Add a row to the table, with table header cells for the
values to be displayed.
- Process the element named "grandfather" which is a child of
the root "family" element.
Note the placement of the xsl:apply-templates element which
performs step 4. The grandfather element will be processed
after the initial table row has been created; this is important
for enabling the second template to create additional rows, one per
element.
The second template rule not only processes the "grandfather"
element but also any "parent" or "child" elements in the document.
<xsl:template match="grandparent|parent|child">
<tr>
<td><xsl:value-of select="name()"/></td>
<td><xsl:value-of select="persname"/></td>
<td><xsl:value-of select="@gender"/></td>
</tr>
<xsl:apply-templates select="parent|child"/>
</xsl:template>
Again reading top to bottom, this template rule says
- The template rule applies to elements named "grandparent,"
"parent," or "child"
- When you find one of these elements, immediately set up a
table row and three table cells
- In the three table cells, display the name of the element
being processed, the value of that element's "persname" child
element, and the value of the "gender" attribute
- Close the table row
- Process any children of the current element whose names are
"parent" or "child"
The last step above is important. Note that, in effect, it makes
the template rule recurse until all elements in the source document
have been processed.
IE displays the result of this stylesheet thus:
Relationship
Name
Gender
grandparent
Morris
male
parent
Betty
female
child
John
male
child
Connie
female
child
Cindy
female
child
Mike
male
Once you've got the hang of this simple application (and have read
DuCharme's "Transforming XML" to alert you to the subtleties and more
advanced features of XSLT), you should be able to extend it easily for
your individual purpose.