Recipe10.1.Using XSLT as a Styling Language


Recipe 10.1. Using XSLT as a Styling Language

Problem

You want the browser to dynamically stylize an XML document into HTML.

Solution

Only an XSLT 1.0 solution is needed. Here is an example for publishing a snippet of a DocBook document in HTML using an XSLT stylesheet. The document source is a portion of this chapter:

<?xml version="1.0" encoding="utf-8"?> <?xml-stylesheet type="application/xml" href="chapter.xsl"?> <chapter label="8">   <chapterinfo>     <author>       <surname>Mangano</surname>       <firstname>Sal</firstname>     </author>     <copyright>       <year>2002</year>       <holder>O'Reilly</holder>     </copyright>   </chapterinfo>   <title>XML to HTML</title>   <epigraph>     <para>That was a surprise to me - that people were prepared to painstakingly  write HTML</para>     <attribution>Tim Berners-Lee</attribution>   </epigraph>   <sect1>     <title>Using XSLT as a Styling Language</title>     <sect2>       <title>Problem</title>       <para>You want to use XSLT to stylize a XML document for dissemination via  HTML.</para>     </sect2>     <sect2>       <title>Solution</title>       <para>Here we show an example for publishing a snippet of        a DocBook document in HTML using a XSLT stylesheet. The document source is a portion of this  chapter.</para>     </sect2>     <sect2>       <title>Discussion</title>       <para>DocBook is an example of a document centric DTD that enables you to  author and store document content in a presentation-neutral form that captures the  logical structure of the content. The beauty of authoring documents (especially  technical ones) in this form is that one can use XSLT to transform a single content  specification into multiple delivery vehicles such as HTML, PDF, Microsoft Help  files, and Unix man pages. Although we present this recipe in terms of DocBook, the  techniques are applicable to other public domain document schema or documents of your  own creation. </para>     </sect2>   </sect1> </chapter>

Notice that the second line of this document includes a processing instruction, xml-stylesheet. This instructs the browser to apply the following stylesheet to the XML and render the stylesheet's output rather than the actual XML. (Remember, this instruction works only in recent browser versions):

<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">   <xsl:output method="html"/>      <xsl:template match="/">     <html>       <head>         <xsl:apply-templates mode="head"/>       </head>       <!-- You may want to use styles in a CSS style element rather -->       <!-- than hardcoding as I do here -->       <body style="margin-left:100;margin-right:100;margin-top:50;margin-bottom:50">         <xsl:apply-templates/>          <xsl:apply-templates select="chapter/chapterinfo/*" mode="copyright"/>        </body>     </html>      </xsl:template>       <!-- Head -->       <xsl:template match="chapter" mode="head">     <xsl:apply-templates select="chapterinfo" mode="head" />     <xsl:apply-templates select="title" mode="head" />   </xsl:template>          <xsl:template match="chapter/title" mode="head">         <title><xsl:value-of select="."/></title>   </xsl:template>       <xsl:template match="author" mode="head">         <meta name="author" content="{concat(firstname,' ', surname)}"/>   </xsl:template>       <xsl:template match="copyright" mode="head">         <meta name="copyright" content="{concat(holder,' ',year)}"/>   </xsl:template>       <xsl:template match="text( )" mode="head"/>     <!-- Body -->      <xsl:template match="chapter">     <div align="right" style="font-size : 48pt; font-family: Times serif;      font-weight : bold; padding-bottom:10; color:red" ><xsl:value-of      select="@label"/></div>     <xsl:apply-templates/>   </xsl:template>         <xsl:template match="chapter/title">     <div align="right" style="font-size : 24pt; font-family: Times serif; padding- bottom:150; color:red"><xsl:value-of select="."/></div>   </xsl:template>       <xsl:template match="epigraph/para">     <div align="right" style="font-size : 10pt; font-family: Times      serif; font-style : italic; padding-top:4; padding-bottom:4">     <xsl:value-of select="."/></div>   </xsl:template>       <xsl:template match="epigraph/attribution">     <div align="right" style="font-size : 10pt; font-family: Times serif; padding- top:4; padding-bottom:4"><xsl:value-of select="."/></div>   </xsl:template>         <xsl:template match="sect1">     <h1 style="font-size : 18pt; font-family: Times serif; font-weight : bold">       <xsl:value-of select="title"/>     </h1>     <xsl:apply-templates/>   </xsl:template>       <xsl:template match="sect2">     <h2 style="font-size : 14pt; font-family: Times serif; font-weight : bold">     <xsl:value-of select="title"/>     </h2>      <xsl:apply-templates/>   </xsl:template>      <xsl:template match="para">     <p style="font-size : 12pt; font-family: Times serif">       <xsl:value-of select="."/>     </p>   </xsl:template>       <xsl:template match="text( )"/>     <xsl:template match="copyright" mode="copyright">   <div style="font-size : 10pt; font-family: Times serif; padding-top : 100">     <xsl:text>Copyright </xsl:text>     <xsl:value-of select="holder"/>     <xsl:text> </xsl:text>     <xsl:value-of select="year"/>     <xsl:text>. All rights reserved.</xsl:text>   </div> </xsl:template>        <xsl:template match="*" mode="copyright"/>     </xsl:stylesheet>

Ultimately, the browser sees the following HTML:

<html>    <head>       <meta name="author" content="Sal Mangano">       <meta name="copyright" content="O'Reilly 2002">       <title>XML to HTML</title>    </head>    <body style="margin-left:100;margin-right:100;margin-top:50;margin-bottom:50">       <div align="right" style="font-size : 48pt; font-family: Times serif; font- weight : bold; padding-bottom:10; color:red">8</div>       <div align="right" style="font-size : 24pt; font-family: Times serif;  padding-bottom:150; color:red">XML to HTML</div>       <div align="right" style="font-size : 10pt; font-family: Times serif; font- style : italic; padding-top:4; padding-bottom:4">That was a surprise to me - that  people were prepared to painstakingly write HTML</div>       <div align="right" style="font-size : 10pt; font-family: Times serif;  padding-top:4; padding-bottom:4">Tim Berners-Lee</div>       <h1 style="font-size : 18pt; font-family: Times serif; font-weight : bold"> Using XSLT as a Styling Language</h1>       <h2 style="font-size : 14pt; font-family: Times serif; font-weight : bold"> Problem</h2>       <p style="font-size : 12pt; font-family: Times serif">You want to use XSLT to  stylize a XML document for dissemination via HTML.</p>       <h2 style="font-size : 14pt; font-family: Times serif; font-weight : bold"> Solution</h2>       <p style="font-size : 12pt; font-family: Times serif">Here we show an example  for publishing a snippet of a DocBook document in HTML using a XSLT stylesheet. The  document source is a portion of this chapter.       </p>       <h2 style="font-size : 14pt; font-family: Times serif; font-weight : bold"> Discussion</h2>       <p style="font-size : 12pt; font-family: Times serif">DocBook is an example of  a document-centric DTD that enables you to author and store document content in a  presentation-neutral form that captures the logical structure of the content. The  beauty of authoring documents (especially technical ones) in this form is that one  can use XSLT to transform a single content specification into multiple delivery  vehicles such as HTML, PDF, Microsoft Help files, and Unix man pages. Although we  present this recipe in terms of DocBook, the techniques are applicable to other  public domain document schema or documents of your own creation.</p>       <div style="font-size : 10pt; font-family: Times serif; padding-top : 100"> Copyright O'Reilly 2002. All rights reserved.</div>    </body> </html>

Discussion

DocBook is a document-centric DTD that enables you to author and store document content in a presentation-neutral form that captures the content's logical structure. The beauty of authoring documents (especially technical ones) in this form is that you can use XSLT to transform a single content specification into multiple delivery vehicles such as HTML, PDF, Microsoft Help files, and Unix manpages. Although the book presents this example in terms of DocBook, the techniques apply to other public-domain document schema or one of your own creation.

Since you only used a subset of the DocBook DTD, creating a simple monolithic stylesheet was convenient. However, an industrial-strength solution would modularize the handling of many DocBook elements by using separate stylesheets and templates that use modes.

One obvious deficiency in the solution is the way style information is hard coded within the stylesheet. Since basic support for Cascading Stylesheets (CSS) is almost universal in today's browsers, a superior solution would delegate transformation to XSLT and styling to CSS.

The stylesheet retains its basic structure, but we replace hard-coded style attributes with class attributes that refer to a stylesheet called style.css that you add to the head element of the html:

<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">   <xsl:output method="html"/>      <xsl:template match="/">     <html>       <head>         <xsl:apply-templates mode="head"/>         <link href="style.css" rel="stylesheet" type="text/css"/>       </head>       <body>         <xsl:apply-templates/>          <xsl:apply-templates select="chapter/chapterinfo/*" mode="copyright"/>        </body>     </html>      </xsl:template>       <!-- Head -->       <xsl:template match="chapter" mode="head">     <xsl:apply-templates select="chapterinfo" mode="head" />     <xsl:apply-templates select="title" mode="head" />   </xsl:template>          <xsl:template match="chapter/title" mode="head">         <title><xsl:value-of select="."/></title>   </xsl:template>       <xsl:template match="author" mode="head">         <meta name="author" content="{concat(firstname,' ', surname)}"/>   </xsl:template>       <xsl:template match="copyright" mode="head">         <meta name="copyright" content="{concat(holder,' ',year)}"/>   </xsl:template>       <xsl:template match="text( )" mode="head"/>     <!-- Body -->      <xsl:template match="chapter">     <div ><xsl:value-of select="@label"/></div>     <xsl:apply-templates/>   </xsl:template>         <xsl:template match="chapter/title">     <div ><xsl:value-of select="."/></div>   </xsl:template>       <xsl:template match="epigraph/para">     <div ><xsl:value-of select="."/></div>   </xsl:template>       <xsl:template match="epigraph/attribution">     <div ><xsl:value-of select="."/></div>   </xsl:template>         <xsl:template match="sect1">     <h1><xsl:value-of select="title"/></h1>     <xsl:apply-templates/>   </xsl:template>       <xsl:template match="sect2">     <h2><xsl:value-of select="title"/></h2>      <xsl:apply-templates/>   </xsl:template>      <xsl:template match="para">     <p ><xsl:value-of select="."/></p>   </xsl:template>       <xsl:template match="text( )"/>     <xsl:template match="copyright" mode="copyright">   <div >     <xsl:text>Copyright </xsl:text>     <xsl:value-of select="holder"/>     <xsl:text> </xsl:text>     <xsl:value-of select="year"/>     <xsl:text>. All rights reserved.</xsl:text>   </div> </xsl:template>        <xsl:template match="*" mode="copyright"/>     </xsl:stylesheet>

A CSS is a simple flat ASCII file (style.css) that follows a simple set of conventions:

body {    margin-left:100;    margin-right:100;    margin-top:50;    margin-bottom:50;    font-family: Times serif;    font-size : 12pt;     color:black;  } div.chapter {    text-align:right;    font-size : 48pt;     font-weight: bold;     padding-bottom:10;     color:red; } div.title {    font-size : 24pt;     font-family: Times serif;     padding-bottom:150;     color:red" } div.epigraph {       font-style:: italic; }  div.epigraph, div.epigraph-attribution {    text-align: right;     font-size : 10pt;     padding-top: 4;     padding-bottom: 4; } h1 {    font-size : 18pt;     font-weight : bold; }  h2 {    font-size : 14pt;     font-weight : bold"; }

If you are unfamiliar with CSS, you can find a nice tutorial at http://www.w3schools.com/css/default.asp. I also recommend Cascading Style Sheets: The Definitive Guide, Second Edition by Eric Meyer, O'Reilly, 2004. In addition, there are many tools available for creating CSS. I am fond of Macromedia Dreamweaver MX, but some might find this tool a bit heavy if all you need is CSS editor.

See Also

The best source for information about DocBook is http://www.docbook.org/. Norman Walsh has developed a set of open source stylesheets to convert DocBook into various publishing formats. These stylesheets are located at http://docbook.sourceforge.net/projects/xsl/.

Recipe 16.2 demonstrates several techniques for creating more modular and extensible stylesheets.




XSLT Cookbook
XSLT Cookbook: Solutions and Examples for XML and XSLT Developers, 2nd Edition
ISBN: 0596009747
EAN: 2147483647
Year: 2003
Pages: 208
Authors: Sal Mangano

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net