Netscape DevEdge

Skip to: [content] [navigation]

XSLT in Netscape Gecko

This article shows how XSLT 1.0 transformations can be run inside Netscape Gecko based clients such as Netscape 7.x as well as other XSLT 1.0 compliant browsers. The article also shows how to generate HTML content from am XML source.

Introduction

One noticeable trend in W3C standards has been the effort to separate content from style. This would allow the same style to be reused for multiple content, as well as simplify maintenance and allow a quick (only modify one file) way to change the look of content.

CSS (Cascade Style Sheets) was one of the first ways proposed by the W3C. CSS is a simple way to apply style rules to a web document. These style rules define how the document (the content) should be laid out. However, it has several limitations, such as lack of programming structures and ability to create complex layout models. CSS also has limited support for changing the position of an element.

XSL (Extensible Stylesheet Language) Transformations are composed of two parts: XSL elements, which allow the transformation of an XML tree into another markup tree and XPath, a selection language for trees. XSLT takes an XML document (the content) and creates a brand new document based on the rules in the XSL stylesheet. This allows XSLT to add, remove and reorganize elements from the original XML document and thus allows more fine-grain control of the resulting document's structure.

Transformations in XSLT are based on rules that consist of templates. Each template matches (using XPath) a certain fragment of the input XML document and then applies the substitution part on that fragment to create the new resulting document.

Basic Example

This first example demonstrates the basics of setting up an XSLT transformation in a browser. The example will take an XML document that contains information (title, list of authors and body text) about an article and present it in an human readable form.

Figure 1 shows the source of the basic XSLT example. The XML document (example.xml) contains the information about the article. Using the ?xml-stylesheet? processing instruction, it links to the XSLT stylesheet (example1.xsl) via its href attribute.

A XSLT stylesheet starts with the xsl:stylesheet element, which contains all the templates used to create the final output. The example in Figure 1 has two templates - one that matches the root node and one that matches Author nodes. The template that matches the root node outputs the article's title and then says to process all templates (via apply-templates) that match Author nodes which are children of the Authors node.

Figure 1 : Simple XSLT Example - view example | XML Document source | XMLT Stylesheet source

XML Document (example1.xml):

  <?xml version="1.0"?>
  <?xml-stylesheet type="text/xsl" href="example.xsl"?>
  <Article>
    <Title>My Article</Title>
    <Authors>
      <Author>Mr. Foo</Author>
      <Author>Mr. Bar</Author>
    </Authors>
    <Body>This is my article text.</Body>
  </Article>

XSL Stylesheet (example1.xsl):

  <?xml version="1.0"?>
  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="text"/>

    <xsl:template match="/">
      Article - <xsl:value-of select="/Article/Title"/>
      Authors: <xsl:apply-templates select="/Article/Authors/Author"/>
    </xsl:template>

    <xsl:template match="Author">
      - <xsl:value-of select="." />
    </xsl:template>

  </xsl:stylesheet>

Browser Output:

  Article - My Article
  Authors:
  - Mr Foo
  - Mr Bar

Generating HTML

One common application of XSLT in the browser is to transform XML into HTML on the client. The second example will transform the input document (example2.xml), which again contains information about an article, into an HTML document.

The <body> element of the article now contains HTML elements (a <b> and <u> tag, see figure 2). The XML document contains both HTML elements and XML elements, but only one namespace is needed, namely for the XML elements. Since there is no HTML namespace, and using the XHTML namespace would force the XSL to create an XML document that would not behave like a HTML document, the xsl:output in the XSL Stylesheet will make sure the resulting document will be handled as HTML. For the XML elements, our own namespace is needed, http://devedge.netscape.com/2002/de, and it is given the prefix myNS (xmlns:myNS="http://devedge.netscape.com/2002/de).

Figure 2 : XML file - view example | view source

XML Document (example2.xml):

  <?xml version="1.0"?>
  <?xml-stylesheet type="text/xsl" href="example2.xsl"?>
  <myNS:Article
                         xmlns:myNS="http://devedge.netscape.com/2002/de">
    <myNS:Title>My Article</myNS:Title>
    <myNS:Authors>
      <myNS:Author company="Foopy Corp.">Mr. Foo</myNS:Author>
      <myNS:Author>Mr. Bar</myNS:Author>
    </myNS:Authors>
    <myNS:Body>
         The <b>rain</b> in <u>Spain</u> stays mainly in the plains.
    </myNS:Body>
  </myNS:Article>

The XSL Stylesheet used will need to have two namespaces - one for the XSLT elements and one for our own XML elements used in the XML document. The output of the XSL Stylesheet is set to HTML by using the xsl:output element. By setting the output to be HTML and not having a namespace on the resulting elements (colored in blue), those elements will be treated as HTML elements.

Figure 3 : XSL Stylesheet with 2 namespaces

XSL Stylesheet (example2.xsl):

  <?xml version="1.0"?>
  <xsl:stylesheet version="1.0"
                           xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                           xmlns:myNS="http://devedge.netscape.com/2002/de">

    <xsl:output method="html"/>
    ...
  </xsl:stylesheet version="1.0">

A template matching the root node of the XML document is created and used to create the basic structure of the HTML page.

Figure 4 : Creating the basic HTML document

XSL Stylesheet (example2.xsl):

  ...
  <xsl:template match="/">
  <html>

    <head>

      <title>
        <xsl:value-of select="/myNS:Article/myNS:Title"/>
      </title>

      <style type="text/css">
        .myBox {margin:10px 155px 0 50px; border: 1px dotted #639ACE; padding:0 5px 0 5px;}
      </style>


    </head>

    <body>
      <p class="myBox">
        <span class="title">
          <xsl:value-of select="/myNS:Article/myNS:Title"/>
        </span> </br>

        Authors:   <br />
          <xsl:apply-templates select="/myNS:Article/myNS:Authors/myNS:Author"/>
      </p>

      <p class="myBox">
        <xsl:apply-templates select="//myNS:Body"/>
      </p>

    </body>

  </html>

  </xsl:template>
  ...

Three more xsl:template's are needed to complete the example. The first xsl:template is used for the author nodes, while the second one processes the body node. The third template has a general matching rule which will match any node and any attribute. It is needed in order to preserve the html elements in the XML document, since it matches all of them and copies them out into the HTML document the transformation creates.

Figure 5 : Final 3 Templates

XSL Stylesheet (example2.xsl):

  ...
  <xsl:template match="myNS:Author">
     --   <xsl:value-of select="." />

    <xsl:if test="@company">
     ::   <b>  <xsl:value-of select="@company" />  </b>
    </xsl:if>

    <br />
  </xsl:template>

  <xsl:template match="myNS:Body">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  ...

The final XSLT stylesheet looks as follows:

Figure 6 : final XSLT Stylesheet - view example | view source

XSL Stylesheet:

  <?xml version="1.0"?>
  <xsl:stylesheet version="1.0"
                           xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                           xmlns:myNS="http://devedge.netscape.com/2002/de">

    <xsl:output method="html" />

    <xsl:template match="/">
      <html>

        <head>

          <title>
            <xsl:value-of select="/myNS:Article/myNS:Title"/>
          </title>

          <style type="text/css">
            .myBox {margin:10px 155px 0 50px; border: 1px dotted #639ACE; padding:0 5px 0 5px;}
          </style>


        </head>

        <body>
          <p class="myBox">
            <span class="title">
              <xsl:value-of select="/myNS:Article/myNS:Title"/>
            </span> </br>

            Authors:   <br />
              <xsl:apply-templates select="/myNS:Article/myNS:Authors/myNS:Author"/>
            </p>

          <p class="myBox">
            <xsl:apply-templates select="//myNS:Body"/>
          </p>

        </body>

      </html>

    </xsl:template>

    <xsl:template match="myNS:Author">
       --   <xsl:value-of select="." />

      <xsl:if test="@company">
       ::   <b>  <xsl:value-of select="@company" />  </b>
      </xsl:if>

      <br />
    </xsl:template>

    <xsl:template match="myNS:Body">
      <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
    </xsl:template>

    <xsl:template match="@*|node()">
        <xsl:copy>
          <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
  </xsl:stylesheet>

Browser Differences

Netscape 7.x (all platforms) and Internet Explorer 6 (Windows) support the W3C XSLT 1.0 standard (http://www.w3.org/TR/xslt). IE 5.0 and 5.5 (both Windows) supported only the working draft of XSLT, and thus are not compatible with XSLT 1.0 stylesheets. Netscape 6.x only partially supported XSLT 1.0.

Resources

A+R