Prerequisites


An XSL document is an XML document whose elements are taken from the namespace http://www.w3 .org/1999/XSL/Format, which is normally given the prefix fo. The XSL document becomes a tree of elements, and that tree of elements is converted into a tree of formatting objects. Each formatting object in the tree describes an output area. A tree of geometric areas is built using the semantics of the corresponding formatting object. These output areas are spread over a series of pages. Areas have a position on the page and a specification of what to display (from the formatting object) and may also have a background, padding, and borders. The following diagram shows an area with background, padding, and borders inside.

click to expand

The area tree is then rendered onto a specific output medium such as PDF or HTML.

XSL’s most significant new component is the notion of pages (or frames). Many features in XSL are related to controlling the usage of space within a page, whether the space is between lines, words, or letters. These features have to work equally well when the pages will be rendered on the Web. Parts of the XSL formatting model are based on CSS2, such as property/trait names and selectors. This provides some transfer of skill and concepts for people who are already familiar with CSS.

Another innovation in XSL is the use of a relative frame of reference for describing the direction of writing. This means XSL can accommodate writing systems where the writing is from left to right, top to bottom; right to left, top to bottom; or top to bottom, right to left. These directions are specified as start to end, before to after, in that order. So for a left to right, top to bottom system, start is the left edge, end is the right edge, before is the top edge, and after is the bottom edge. For a top to bottom, right to left system, start is the top edge, end is the bottom edge, before is the right edge, and after is the left edge.

Basic XSL

Let’s look at a simple XSL document and examine its components. The root element of the XSL document is fo:root, using the fo prefix according to convention:

  1: <?xml version="1.0" encoding="UTF-8"?>   2: <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

The XSL document begins with a set of name layout masters, one for each different kind of page layout to be used in the output document. Here you define a single page master using the fo:simple-page-master element. The definition specifies the margins all around from the edge of the page and also specifies a separate uniform margin around the region body:

  3:  <fo:layout-master-set>   4:   <fo:simple-page-master margin-right="0.5in" margin-left="0.5in"   5:       margin-bottom="0.5in" margin-top="0.5in" page-width="8.5in"   6:       page-height="11in" master-name="book-page">   7:    <fo:region-body margin="1in"/>   8:   </fo:simple-page-master>   9:  </fo:layout-master-set>

Flows

Page sequences contain flows. There are two types of flows, <fo:flow> flows and <fo:static-content> flows. <fo:flow> flows contain content that’s distributed across a sequence of pages. <fo:static-content> flows are used for text that will be repeated on many pages, like a header or footer. In this example, a single <fo:flow> is connected to the region-body section of the page (see figure 4.1) by using “xsl-region-body” as the value of the flow-name attribute on <fo:flow> (line 11):

 10:  <fo:page-sequence master-reference="book-page">  11:   <fo:flow flow-name="xsl-region-body">  12:    <fo:block>

You can also specify flows to be connected to region-before, region-after, region-start, or region-end, by specifying a different flow name for the flow-name attribute of <fo:flow>. The flow names are xsl-region-before, xsl-region-after, xsl-region-start, and xsl-region-end. Attaching flows to the other regions allows you to do things like headers, footers, and sidebars.

The contents of a flow are a series of flow objects. There are two primary classes of flow objects: block-level flow objects, such as <fo:block>, <fo:list-block>, and <fo:table>; and inline flow objects, such as <fo:inline>, <fo:external-graphic>, and <fo:page-number>. The block-level flow objects are for formatting blocks of text, such as paragraphs, titles, captions, and so on, whereas inline flow objects are for formatting text without starting a new block. The flow objects can have attributes that control various aspects of formatting. For block flow objects, you can control line height, text alignment, indentation, font style and size, color, borders, and many other aspects. Specifying fonts can be done very flexibly; you can have separate attributes such as font-family, font-style, font-weight, and color. You can also use the font attribute and write shorthand specifications that look like this: font=”bold 16pt Helvetica”. Unfortunately, FOP 20.5 doesn’t support the font=”” style shortcuts, so you must use the separate attributes to specify font information. For inline flow objects, some of the aspects you can control are line height, font style and size, and color.

List Blocks

The example XSL document uses a list block to present the books in the books inventory file. In XSL, an <fo:list-block> does more than create bulleted or numbered lists; it provides a way to place two blocks side by side. Both the <fo:list-item-label> and the <fo:list-item-body> contain blocks that are placed side by side inside the block for the <fo:list-block>:

 13:     <fo:list-block provisional-label-separation="3pt"   14:         provisional-distance-between-starts="18pt">  15:      <fo:list-item>  16:       <fo:list-item-label>  17:        <fo:block space-after.optimum="15pt">  18:         <fo:inline font-size="14pt">  19:          ?—  Professional XML Development with Apache Tools  20:         </fo:inline>  21:        </fo:block>  22:       </fo:list-item-label>  23:       <fo:list-item-body>  24:        <fo:block space-after.optimum="15pt">  25:         <fo:inline   26:             font-weight="bold">Theodore W. Leung</fo:inline>  27:         <fo:inline>0-7645-4355-5</fo:inline>  28:         <fo:inline>December, </fo:inline>  29:         <fo:inline>2003</fo:inline>  30:         <fo:inline>Wrox</fo:inline>  31:         <fo:inline>Indianapolis, Indiana</fo:inline>  32:        </fo:block>  33:       </fo:list-item-body>

Inside the <fo:list-item-label> is an explicit block you use to control the spacing of the text after the label. You also use an <fo:inline> to control the font size of the item label. Like the <fo:list-item-label>, the <fo:list-item-body> includes an <fo:block> that controls the spacing after the block. Within the block, you again use <fo:inline>s to control the formatting of different parts of the block content.

The rest of the document is as follows:

 34:      </fo:list-item>  35:      <fo:list-item>  36:       <fo:list-item-label>  37:        <fo:block space-after.optimum="15pt">  38:         <fo:inline font-size="14pt">  39:         ?—  Effective Java</fo:inline>  40:        </fo:block>  41:       </fo:list-item-label>  42:       <fo:list-item-body>  43:        <fo:block space-after.optimum="15pt">  44:         <fo:inline font-weight="bold">Joshua Bloch</fo:inline>  45:         <fo:inline>0-201-31005-8</fo:inline>  46:         <fo:inline>August, </fo:inline>  47:         <fo:inline>2001</fo:inline>  48:         <fo:inline>Addison-Wesley</fo:inline>  49:         <fo:inline>New York, New York</fo:inline>  50:        </fo:block>  51:       </fo:list-item-body>  52:      </fo:list-item>  53:      <fo:list-item>  54:       <fo:list-item-label>  55:        <fo:block space-after.optimum="15pt">  56:         <fo:inline font-size="14pt">  57:         ?—  Design Patterns</fo:inline>  58:        </fo:block>  59:       </fo:list-item-label>  60:       <fo:list-item-body>  61:        <fo:block space-after.optimum="15pt">  62:         <fo:inline font-weight="bold">Erich Gamma</fo:inline>  63:         <fo:inline font-weight="bold">Richard Helm</fo:inline>  64:         <fo:inline font-weight="bold">Ralph Johnson</fo:inline>  65:         <fo:inline font-weight="bold">John Vlissides</fo:inline>  66:         <fo:inline>0-201-63361-2</fo:inline>  67:         <fo:inline>October, </fo:inline>  68:         <fo:inline>1994</fo:inline>  69:         <fo:inline>Addison-Wesley</fo:inline>  70:         <fo:inline>Reading, Massachusetts</fo:inline>  71:        </fo:block>  72:       </fo:list-item-body>  73:      </fo:list-item>  74:     </fo:list-block>  75:    </fo:block>  77:   </fo:flow>  78:  </fo:page-sequence>  79: </fo:root>

Generating XSL with XSLT

Let’s look at how the XSL document was generated from the book inventory. A common method of generating XSL documents is to use XSLT, which makes sense because the two specifications were designed to work together. This isn’t the only method, of course. You could write an application that generated the XSL file directly and sent it to FOP; if you were concerned about performance, you might consider doing this. However, you’d give up a lot of flexibility. Taking XML data and using XSLT to convert it to XSL gives you much more flexibility because you can do other things with that XML. If you generate XSL directly, you lose the ability to repurpose the data at some later point. Here is an XSLT stylesheet that generates an XSL file based on the books.xml datafile.

  1: <?xml version="1.0" encoding="UTF-8"?>   2: <xsl:stylesheet version="1.0"    3:   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"   4:   xmlns:books="http://sauria.com/schemas/apache-xml-book/books"   5:   xmlns:fo="http://www.w3.org/1999/XSL/Format"   6:   exclude-result-prefixes="books">

Note that you declare the fo namespace prefix for use in the rest of the stylesheet.

The template for the root of the books document creates the shell of the XSL document and then allows templates for the child elements of the <books:books> element to do their job:

  7:     <xsl:output method="xml" version="1.0" encoding="UTF-8"    8:         indent="yes"/>   9:   10:     <xsl:template match="books:books">  11:      <fo:root>  12:       <fo:layout-master-set>  13:        <fo:simple-page-master master-name="book-page"  14:         page-height="11in" page-width="8.5in"  15:         margin-top="0.5in" margin-bottom="0.5in"  16:         margin-left="0.5in" margin-right="0.5in">  17:         <fo:region-body margin="1in"/>  18:        </fo:simple-page-master>  19:       </fo:layout-master-set>  20:         21:       <fo:page-sequence master-reference="book-page">  22:        <fo:flow flow-name="xsl-region-body">  23:         <fo:block>  24:          <fo:list-block   25:              provisional-distance-between-starts="18pt"  26:              provisional-label-separation="3pt">  27:           <xsl:apply-templates/>  28:          </fo:list-block>  29:         </fo:block>  30:        </fo:flow>  31:       </fo:page-sequence>  32:      </fo:root>  33:     </xsl:template>  34:     

In this template, you use the | operator from XPath to apply templates to a subset of the children of <books:book>. This is a nice, flexible approach, and it uses only a little more space than listing the elements you want selected:

 35:     <xsl:template match="books:book">  36:      <fo:list-item>  37:       <xsl:apply-templates select="books:title"/>  38:       <fo:list-item-body>  39:        <!-- need this to prevent garbling -->  40:        <fo:block space-after.optimum="15pt">   41:         <xsl:apply-templates   42:           select="books:author | books:isbn | books:month |   43:                   books:year | books:publisher | books:address"/>  44:        </fo:block>  45:       </fo:list-item-body>  46:      </fo:list-item>  47:     </xsl:template>  48: 

The remainder of the stylesheet looks similar to what you saw in Chapter 2, “Xalan,” except you’re generating XSL instead of HTML. So, you’re seeing a demonstration of the versatility of XSLT in action:

 49:     <xsl:template match="books:title">  50:      <fo:list-item-label>  51:       <fo:block space-after.optimum="15pt">   52:        <fo:inline font-size="14pt">  53:         &#x2022; <xsl:value-of select="."/>  54:        </fo:inline>  55:       </fo:block>  56:      </fo:list-item-label>  57:     </xsl:template>  58:   59:     <xsl:template match="books:author">  60:       <fo:inline font-weight="bold">  61:        <xsl:value-of select="."/>  62:       </fo:inline>  63:     </xsl:template>  64:   65:     <xsl:template match="books:isbn">  66:       <fo:inline><xsl:value-of select="."/></fo:inline>  67:     </xsl:template>  68:   69:     <xsl:template match="books:month">  70:       <fo:inline><xsl:value-of select="."/>, </fo:inline>  71:     </xsl:template>  72:   73:     <xsl:template match="books:year">  74:       <fo:inline><xsl:value-of select="."/></fo:inline>  75:     </xsl:template>  76:   77:     <xsl:template match="books:publisher">  78:       <fo:inline><xsl:value-of select="."/></fo:inline>  79:     </xsl:template>  80:   81:     <xsl:template match="books:address">  82:       <fo:inline><xsl:value-of select="."/></fo:inline>  83:     </xsl:template>  84: </xsl:stylesheet>

Tables

Let’s look at one other XSL document that includes a table. Lists and tables are two important items you need to be familiar with in order to format business information. (Those of you who are more interested in publishing types of applications will need much more detail on XSL than we can present in this chapter.) The key thing is that you must specify all the table columns explicitly using <fo:table-column>, including their width (the column-width attribute):

  1: <?xml version="1.0" encoding="UTF-8"?>   2: <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">   3:  <fo:layout-master-set>   4:   <fo:simple-page-master margin-right="0.5in" margin-left="0.5in"   5:       margin-bottom="0.5in" margin-top="0.5in" page-width="8.5in"   6:       page-height="11in" master-name="book-page">   7:    <fo:region-body margin="1in"/>   8:   </fo:simple-page-master>   9:  </fo:layout-master-set>  10:  <fo:page-sequence master-reference="book-page">  11:   <fo:flow flow-name="xsl-region-body">  12:    <fo:block>  13:     <fo:table>  14:      <fo:table-column column-width="2.0in"/>  15:      <fo:table-column column-width="1.5in"/>  16:      <fo:table-column column-width="0.5in"/>  17:      <fo:table-column column-width="2.0in"/>

Once you’ve specified the columns, you can specify a header for the table (<fo:table-header>), which contains one table cell for each column. Note that the content of each table cell is a block:

 18:      <fo:table-header>  19:       <fo:table-row>  20:        <fo:table-cell>  21:         <fo:block>Title</fo:block>  22:        </fo:table-cell>  23:        <fo:table-cell>  24:         <fo:block>ISBN</fo:block>  25:        </fo:table-cell>  26:        <fo:table-cell>  27:         <fo:block>Year</fo:block>  28:        </fo:table-cell>  29:        <fo:table-cell>  30:         <fo:block>Publisher</fo:block>  31:        </fo:table-cell>  32:       </fo:table-row>  33:      </fo:table-header>

The body of the table (enclosed in <fo:table-body>) is composed of rows (<fo:table-row>) that contain table cells, one for each column in the row:

 34:      <fo:table-body>  35:       <fo:table-row>  36:        <fo:table-cell>  37:           <fo:block>Professional XML Development with Apache Tools</fo:block>  38:        </fo:table-cell>  39:        <fo:table-cell>  40:         <fo:block>0-7645-4355-5</fo:block>  41:        </fo:table-cell>  42:        <fo:table-cell>  43:         <fo:block>2003</fo:block>  44:        </fo:table-cell>  45:        <fo:table-cell>  46:         <fo:block>Wrox </fo:block>  47:        </fo:table-cell>  48:       </fo:table-row>  49:       <fo:table-row>  50:        <fo:table-cell>  51:         <fo:block>Effective Java</fo:block>  52:        </fo:table-cell>  53:        <fo:table-cell>  54:         <fo:block>0-201-31005-8</fo:block>  55:        </fo:table-cell>  56:        <fo:table-cell>  57:         <fo:block>2001</fo:block>  58:        </fo:table-cell>  59:        <fo:table-cell>  60:         <fo:block>Addison-Wesley</fo:block>  61:        </fo:table-cell>  62:       </fo:table-row>  63:       <fo:table-row>  64:        <fo:table-cell>  65:         <fo:block>Design Patterns</fo:block>  66:        </fo:table-cell>  67:        <fo:table-cell>  68:         <fo:block>0-201-63361-2</fo:block>  69:        </fo:table-cell>  70:        <fo:table-cell>  71:         <fo:block>1994</fo:block>  72:        </fo:table-cell>  73:        <fo:table-cell>  74:         <fo:block>Addison-Wesley</fo:block>  75:        </fo:table-cell>  76:       </fo:table-row>  77:      </fo:table-body>  78:     </fo:table>  79:    </fo:block>  80:   </fo:flow>  81:  </fo:page-sequence>  82: </fo:root>

The XSLT stylesheet for generating the table version of the XSL file is shown here:

  1: <?xml version="1.0" encoding="UTF-8"?>   2: <xsl:stylesheet version="1.0"    3:   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"   4:   xmlns:books="http://sauria.com/schemas/apache-xml-book/books"   5:   xmlns:fo="http://www.w3.org/1999/XSL/Format"   6:   exclude-result-prefixes="books">   7:     <xsl:output method="xml" version="1.0" encoding="UTF-8"    8:         indent="yes"/>   9:   10:     <xsl:template match="books:books">  11:      <fo:root>  12:       <fo:layout-master-set>  13:        <fo:simple-page-master master-name="book-page"  14:         page-height="11in" page-width="8.5in"  15:         margin-top="0.5in" margin-bottom="0.5in"  16:         margin-left="0.5in" margin-right="0.5in">  17:         <fo:region-body margin="1in"/>  18:        </fo:simple-page-master>  19:       </fo:layout-master-set>  20:         21:       <fo:page-sequence master-reference="book-page">  22:        <fo:flow flow-name="xsl-region-body">  23:         <fo:block>  24:          <fo:table>  25:           <fo:table-column column-width="2.0in"/>  26:           <fo:table-column column-width="1.5in"/>  27:           <fo:table-column column-width="0.5in"/>  28:           <fo:table-column column-width="2.0in"/>  29:           <fo:table-header>  30:            <fo:table-row>  31:            <fo:table-cell>  32:            <fo:block>Title</fo:block>  33:            </fo:table-cell>  34:            <fo:table-cell>  35:            <fo:block>ISBN</fo:block>  36:            </fo:table-cell>  37:            <fo:table-cell>  38:            <fo:block>Year</fo:block>  39:            </fo:table-cell>  40:            <fo:table-cell>  41:            <fo:block>Publisher</fo:block>  42:            </fo:table-cell>  43:         </fo:table-row>  44:         </fo:table-header>  45:           <fo:table-body>  46:            <xsl:apply-templates/>  47:           </fo:table-body>  48:          </fo:table>  49:         </fo:block>  50:        </fo:flow>  51:       </fo:page-sequence>  52:      </fo:root>  53:     </xsl:template>  54:       55:     <xsl:template match="books:book">  56:      <fo:table-row>  57:       <xsl:apply-templates select="books:title | books: author |  58:       books:isbn | books:year | books:publisher"/>  59:      </fo:table-row>  60:     </xsl:template>  61:   62:     <xsl:template match="books:title">  63:      <fo:table-cell>  64:       <fo:block>  65:        <xsl:value-of select="."/>  66:       </fo:block>  67:      </fo:table-cell>  68:     </xsl:template>  69:   70:     <xsl:template match="books:author"/>  71:   72:     <xsl:template match="books:isbn">  73:      <fo:table-cell>  74:       <fo:block><xsl:value-of select="."/></fo:block>  75:     </fo:table-cell>  76:     </xsl:template>  77:   78:     <xsl:template match="books:month">  79:      <fo:table-cell>  80:       <fo:block><xsl:value-of select="."/></fo:block>  81:      </fo:table-cell>  82:     </xsl:template>  83:   84:     <xsl:template match="books:year">  85:      <fo:table-cell>  86:       <fo:block><xsl:value-of select="."/></fo:block>  87:     </fo:table-cell>  88:     </xsl:template>  89:   90:     <xsl:template match="books:publisher">  91:      <fo:table-cell>  92:       <fo:block><xsl:value-of select="."/></fo:block>  93:      </fo:table-cell>  94:     </xsl:template>  95:   96:     <xsl:template match="books:address">  97:      <fo:table-cell>  98:       <fo:block><xsl:value-of select="."/></fo:block>  99:      </fo:table-cell> 100:     </xsl:template> 101: </xsl:stylesheet>

The XSL specification is large, and at the time of this writing FOP doesn’t support everything in the specification. Every FOP distribution contains a documentation page that includes a large table showing which XSL features are supported in that version of FOP. The safest way to proceed is to look at that page for the FOP distribution you’re using. You can also consult the FOP user’s mailing list (directions for finding this are in the documentation) if you’re unsure whether a particular feature is supported.




Professional XML Development with Apache Tools. Xerces, Xalan, FOP, Cocoon, Axis, Xindice
Professional XML Development with Apache Tools: Xerces, Xalan, FOP, Cocoon, Axis, Xindice (Wrox Professional Guides)
ISBN: 0764543555
EAN: 2147483647
Year: 2003
Pages: 95

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