Generating HTML

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 :(example2.xml)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 (example2.xsl) 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 Stylesheetview 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>