October 31, 2006
Harvard University
Division of Continuing Education
ExtensionSchool
Course Web Site: http://cscie153.dce.harvard.edu/
Copyright 2003-2006 David P. Heitmeyer
Instructor email:
david_heitmeyer@harvard.edu
Course staff email:
cscie153@fas.harvard.edu
Electronic data and online availability of information has not (yet?) created a paperless world.
Some examples from some Harvard projects:
| Why? |
W3C Extensible Stylesheet Language, XSL 1.0
15 October 2001
Output from an XSL-FO Formatter could be
minerva% fop
USAGE
Fop [options] [-fo|-xml] infile [-xsl file] [-awt|-pdf|-mif|-pcl|-ps|-txt|-at|-print] <outfile>
[OPTIONS]
-d debug mode
-x dump configuration settings
-q quiet mode
-c cfg.xml use additional configuration file cfg.xml
-l lang the language to use for user information
-s (-at output) omit tree below block areas
-txt.encoding (-txt output encoding use the encoding for the output file.
The encoding must be a valid java encoding.
-o [password] pdf file will be encrypted with option owner password
-u [password] pdf file will be encrypted with option user password
-noprint pdf file will be encrypted without printing permission
-nocopy pdf file will be encrypted without copy content permission
-noedit pdf file will be encrypted without edit content permission
-noannotations pdf file will be encrypted without edit annotation permission
[INPUT]
infile xsl:fo input file (the same as the next)
-fo infile xsl:fo input file
-xml infile xml input file, must be used together with -xsl
-xsl stylesheet xslt stylesheet
[OUTPUT]
outfile input will be rendered as pdf file into outfile
-pdf outfile input will be rendered as pdf file (outfile req'd)
-awt input will be displayed on screen
-mif outfile input will be rendered as mif file (outfile req'd)
-pcl outfile input will be rendered as pcl file (outfile req'd)
-ps outfile input will be rendered as PostScript file (outfile req'd)
-txt outfile input will be rendered as text file (outfile req'd)
-svg outfile input will be rendered as an svg slides file (outfile req'd)
-at outfile representation of area tree as XML (outfile req'd)
-print input file will be rendered and sent to the printer
see print specific options with "-print help"
[Examples]
Fop foo.fo foo.pdf
Fop -fo foo.fo -pdf foo.pdf (does the same as the previous line)
Fop -xsl foo.xsl -xml foo.xml -pdf foo.pdf
Fop foo.fo -mif foo.mif
Fop foo.fo -print or Fop -print foo.fo
Fop foo.fo -awtWhen first learning XSL-FO, start with writing the FO file. Then, write the XSLT stylesheet to transform your XML into the XSL-FO. Use Xalan or Saxon to transform your XML into XSL-FO; then use Apache FOP on the XSL-FO file to generate PDF.
When you get the hang of it, you can skip generating an XSL-FO file; given an XML file and an XSLT file, Apache FOP can generate a PDF (the XSL-FO is created in memory).
<map:match pattern="**.fo.pdf">
<map:generate src="{1}.fo"/>
<map:serialize type="fo2pdf"/>
</map:match>
minerva% fop ex1.fo ex1.pdf [INFO] Using org.apache.xerces.parsers.SAXParser as SAX2 Parser [INFO] FOP 0.20.5 [INFO] Using org.apache.xerces.parsers.SAXParser as SAX2 Parser [INFO] building formatting object tree [INFO] setting up fonts [INFO] [1] [INFO] Parsing of document complete, stopping renderer
<fo:block font-size="14pt"
font-family="sans-serif"
line-height="20pt"
space-after.optimum="12pt"
color="#990000"
text-align="center"
padding-top="3pt">
CSCI E-153, Website Development Using XML
</fo:block>processing...
minerva% fop ex2.fo ex2.pdf [INFO] Using org.apache.xerces.parsers.SAXParser as SAX2 Parser [INFO] FOP 0.20.5 [INFO] Using org.apache.xerces.parsers.SAXParser as SAX2 Parser [INFO] building formatting object tree [INFO] setting up fonts [INFO] [1] [INFO] Parsing of document complete, stopping renderer
<!-- list -->
<fo:list-block>
<!-- list item -->
<fo:list-item>
<!-- insert a bullet -->
<fo:list-item-label end-indent="label-end()">
<fo:block>
<fo:inline font-family="Symbol">•
</fo:inline>
</fo:block>
</fo:list-item-label>
<!-- list text -->
<fo:list-item-body start-indent="body-start()">
<fo:block>rake leaves</fo:block>
</fo:list-item-body>
</fo:list-item>
<!-- list item -->
<fo:list-item>
<!-- insert a bullet -->
<fo:list-item-label end-indent="label-end()">
<fo:block>
<fo:inline font-family="Symbol">•
</fo:inline>
</fo:block>
</fo:list-item-label>
<!-- list text -->
<fo:list-item-body start-indent="body-start()">
<fo:block>put in driveway snow plow markers</fo:block>
</fo:list-item-body>
</fo:list-item>
<fo:list-item>
<!-- insert a bullet -->
<fo:list-item-label end-indent="label-end()">
<fo:block>
<fo:inline font-family="Symbol">♠
</fo:inline>
</fo:block>
</fo:list-item-label>
<!-- list text -->
<fo:list-item-body start-indent="body-start()">
<fo:block>bring in patio furniture</fo:block>
</fo:list-item-body>
</fo:list-item>
</fo:list-block>
In XSL
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" version="1.0">
Have the template that matches on "/" take care of the XSL-FO "scaffolding", and do the work of the content in other templates:
<xsl:template match="state">
<fo:block font-size="12pt" font-family="sans-serif" line-height="15pt"
space-after.optimum="3pt">
<xsl:value-of select="@abbreviation"/>
<xsl:text>: </xsl:text>
<xsl:value-of select="@name"/>
</fo:block>
</xsl:template>Three ways:


minerva% java org.apache.xalan.xslt.Process -in usps.xml -xsl ex4.xsl -out ex4-usps.fo minerva% fop ex4-usps.fo ex4-usps.pdf [INFO] Using org.apache.xerces.parsers.SAXParser as SAX2 Parser [INFO] FOP 0.20.5 [INFO] Using org.apache.xerces.parsers.SAXParser as SAX2 Parser [INFO] building formatting object tree [INFO] setting up fonts [INFO] [1] [INFO] [2] [INFO] Parsing of document complete, stopping renderer

Fop:
minerva% fop \ > -xml usps.xml \ > -xsl ex4.xsl \ > -pdf ex4-usps.pdf [INFO] Using org.apache.xerces.parsers.SAXParser as SAX2 Parser [INFO] FOP [INFO] Using org.apache.xerces.parsers.SAXParser as SAX2 Parser [INFO] building formatting object tree [INFO] setting up fonts [INFO] [1] [INFO] [2] [INFO] Parsing of document complete, stopping renderer
<map:match pattern="fo/usps/ex*.pdf">
<map:generate src="fo/usps.xml" type="file"/>
<map:transform src="fo/ex{1}.xsl" type="xslt"/>
<map:serialize type="fo2pdf"/>
</map:match>
XSLT
Set up table:
<fo:table>
<fo:table-column column-width="1in"/>
<fo:table-column column-width="4in"/>
<fo:table-body>
<xsl:apply-templates select="/usps/state"/>
</fo:table-body>
</fo:table>Each state gets a table row:
<xsl:template match="state">
<fo:table-row>
<fo:table-cell>
<fo:block>
<xsl:value-of select="@abbreviation"/>
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>
<xsl:value-of select="@name"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:template>Fop:
minerva% fop -xml usps.xml \ > -xsl ex5.xsl \ > -pdf ex5-usps.pdf [INFO] Using org.apache.xerces.parsers.SAXParser as SAX2 Parser [INFO] FOP 0.20.5 [INFO] Using org.apache.xerces.parsers.SAXParser as SAX2 Parser [INFO] building formatting object tree [INFO] setting up fonts [INFO] [1] [WARNING] table-layout=auto is not supported, using fixed! [INFO] [2] [INFO] Parsing of document complete, stopping renderer
XSLT
Define attribute sets as a child of xsl:stylesheet:
<!-- define attribute set in XSLT -->
<xsl:attribute-set name="normal">
<xsl:attribute name="font-family">Times, serif</xsl:attribute>
<xsl:attribute name="font-size">12pt</xsl:attribute>
</xsl:attribute-set>And then use it:
<!-- and later on use it -->
<xsl:template match="state">
<fo:table-row>
<fo:table-cell>
<fo:block xsl:use-attribute-sets="normal">
<xsl:value-of select="@abbreviation"/>
</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block xsl:use-attribute-sets="normal">
<xsl:value-of select="@name"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:template>Fop
minerva% fop -xml usps.xml \ > -xsl ex6.xsl \ > -pdf ex6-usps.pdf [INFO] Using org.apache.xerces.parsers.SAXParser as SAX2 Parser [INFO] FOP 0.20.5 [INFO] Using org.apache.xerces.parsers.SAXParser as SAX2 Parser [INFO] building formatting object tree [INFO] setting up fonts [INFO] [1] [WARNING] table-layout=auto is not supported, using fixed! [INFO] [2] [INFO] Parsing of document complete, stopping renderer
Define multiple attribute sets:
<xsl:attribute-set name="normal">
<xsl:attribute name="font-family">Helvetica, sans-serif</xsl:attribute>
<xsl:attribute name="font-size">14pt</xsl:attribute>
</xsl:attribute-set>
<xsl:attribute-set name="alert">
<xsl:attribute name="background-color">#ffff00</xsl:attribute>
<xsl:attribute name="color">#ff0000</xsl:attribute>
</xsl:attribute-set>Apply more than one attribute set:
<fo:block xsl:use-attribute-sets="normal alert">
<xsl:value-of select="@abbreviation"/>
</fo:block><!-- child of fo:table -->
<fo:table-header>
<fo:table-row background-color="#ccccff">
<fo:table-cell padding="0.5em">
<fo:block text-align="center" font-weight="bold">
Abbreviation
</fo:block>
</fo:table-cell>
<fo:table-cell padding="0.5em">
<fo:block text-align="center" font-weight="bold">
State Name
</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-header>
usps.jpg
<!-- insert external graphic --> <fo:block text-align="center"> <fo:external-graphic src="url(usps.jpg)"/> </fo:block>
minerva% fop -xml conferences.xml \ > -xsl ex9.xsl \ > -pdf ex9-conferences.pdf [INFO] Using org.apache.xerces.parsers.SAXParser as SAX2 Parser [INFO] FOP 0.20.5 [INFO] Using org.apache.xerces.parsers.SAXParser as SAX2 Parser [INFO] building formatting object tree [INFO] setting up fonts [INFO] [1] [INFO] Parsing of document complete, stopping renderer
<xsl:for-each select="/conferences/school
[generate-id() =
generate-id(key('conference-group',@conference)[1])
]">
<xsl:sort select="@conference"/>
<fo:block break-before="page"
xsl:use-attribute-sets="conference-title">
<xsl:value-of select="@conference"/>
</fo:block>
<xsl:for-each select="key('conference-group',@conference)">
<xsl:sort select="@name"/>
<fo:block xsl:use-attribute-sets="normal">
<xsl:value-of select="@name"/>
</fo:block>
</xsl:for-each>
</xsl:for-each><fo:page-sequence master-reference="simple">
<!-- fo:static-content for header -->
<fo:static-content flow-name="xsl-region-before">
<fo:block font-size="8pt" text-align="end">
Conferences, Page
<fo:page-number/>
</fo:block>
</fo:static-content>
....<!-- generate table of contents -->
<fo:block>
<xsl:for-each select="/conferences/school
[generate-id() =
generate-id(key('conference-group',@conference)[1])
]">
<xsl:sort select="@conference"/>
<fo:block text-align-last="justify">
<xsl:value-of select="@conference"/>
<fo:leader leader-pattern="dots"/>
<fo:page-number-citation>
<xsl:attribute name="ref-id">
<xsl:value-of select="generate-id()"/>
</xsl:attribute>
</fo:page-number-citation>
</fo:block>
</xsl:for-each>
</fo:block><fo:basic-link>
<xsl:attribute name="internal-destination">
<xsl:value-of select="generate-id()"/>
</xsl:attribute>
<xsl:value-of select="@conference"/>
</fo:basic-link>
<map:match pattern="fo/usps/ex*.rtf">
<map:generate src="fo/usps.xml"/>
<map:transform src="fo/ex{1}.xsl"/>
<map:serialize type="fo2rtf"/>
</map:match>
XSL-FO: Making XML Look Good in Print
, by Dave Pawson, O'Reilly, 2002.
SVG is a language for describing two-dimensional graphics and graphical applications in XML. SVG 1.1 is a W3C Recommendation and forms the core of the current SVG developments. SVG 1.2 is the specification currently being developed as is available in draft form (comments welcome). The SVG Mobile Profiles: SVG Basic and SVG Tiny are targetted to resource-limited devices and are part of the 3GPP platform for third generation mobile phones. SVG Print is a set of guidelines to produce final-form documents in XML suitible for archiving and printing.
Bitmap GraphicBitmap Graphic Formats on the Web
Graphic type in which each pixel that comprises the image is described.
A 100 x 100 pixel bitmap image must encode information about 10,000 pixels. | Vector GraphicVector Graphic Formats on the Web
Graphic type in which the image is described by a mathematical description.
Amount of information encoded is independent of the scale of image. For example, a circle is described by the equation |
Original image:
![]() |
Magnified (16x)![]() |
| Original image:
|
Magnified (16x)![]() |
Batik SVG Toolkit comes with an SVG viewer, "Squiggle":
java -jar batik-squiggle.jar
On minerva, the latest version of batik is at /usr/local/batik/

sitemap.xmap entry:
<map:pipeline>
<map:match pattern="svg/*.jpg">
<map:generate src="svg/{1}.svg"/>
<map:serialize type="svg2jpeg"/>
</map:match>
<map:match pattern="svg/*.png">
<map:generate src="svg/{1}.svg"/>
<map:serialize type="svg2png"/>
</map:match>
<map:match pattern="svg/*.svg">
<map:generate src="svg/{1}.svg"/>
<map:serialize type="xml" mime-type="image/svg+xml"/>
</map:match>
</map:pipeline>Cocoon Directory:
cocoon
|-- sitemap.xmap
`-- svg
`-- flag.svg
<img src="example_svg/flag.png" alt="United States Flag"/>

<img src="example_svg/flag.jpg" />

<object data="example_svg/flag.svg" title="United States Flag" height="240" width="370"/>
An if you need compatibility with HTML, use the "embed" element:
<embed src="example_svg/flag.svg" alt="United States Flag" height="240" width="370"/>
General Resources:
Specific Articles:
The World Wide Web -- away from your desktop.
"Mobile access to the Web has been a second class experience for far too long," explained Tim Berners-Lee, W3C Director. "MWI recognizes the mobile device as a first class participant, and will produce materials to help developers make the mobile Web experience worthwhile. "
Mobile Web Design - The Series from Authentic Boredom.
The Harvard College Admissions Site, designed with multiple environments in mind...
With CSS: ![]() | "Opera" Small Screen view: ![]() |
With No CSS: ![]() |
We will focus on XHTML Mobile Profile and XHTML Basic.
Reading:

INCLUDE and IGNORE directives in DTDs allow to selectively include XHTML modules, including whether or not prefix is present.
<![IGNORE[
<!ENTITY % xhtml-image.mod
PUBLIC "-//W3C//ELEMENTS XHTML Images 1.0//EN"
"xhtml-image-1.mod" >
%xhtml-image.mod;]]>
<![INCLUDE[
<!ENTITY % xhtml-image.mod
PUBLIC "-//W3C//ELEMENTS XHTML Images 1.0//EN"
"xhtml-image-1.mod" >
%xhtml-image.mod;]]>
<!ENTITY % xhtml-image.module "INCLUDE" >
<![%xhtml-image.module;[
<!ENTITY % xhtml-image.mod
PUBLIC "-//W3C//ELEMENTS XHTML Images 1.0//EN"
"xhtml-image-1.mod" >
%xhtml-image.mod;]]>
As an example look at the XHTML Basic 1.0 DTD
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.0//EN"
"http://www.w3.org/TR/xhtml-basic/xhtml-basic10.dtd">XHTML Basic consists of the following XHTML modules:
body, head, html, titleabbr, acronym, address, blockquote, br, cite, code, dfn, div, em,
h1, h2, h3, h4, h5, h6, kbd, p, pre, q, samp, span, strong, varadl, dt, dd, ol, ul, liform, input, label, select, option, textareacaption, table, td, th, trimgobject, parammetalinkbase<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd">
A variety of XHTML flavors: XHTML 1.0 Strict, XHTML 1.0 Transitional, XHTML Basic 1.0, XHTML 1.1, and XHTML Mobile Profile 1.0. We need to provide the appropriate:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.0//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic10.dtd">
<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.0//EN" "http://www.wapforum.org/DTD/xhtml-mobile10.dtd">
The xsl:output element allows us to control the document type declaration as well as other aspects of the XML output producted.
<xsl:output method="xml" encoding="utf-8" omit-xml-declaration="no" doctype-public="http://www.w3.org/TR/xhtml-basic/xhtml-basic10.dtd" doctype-system="-//W3C//DTD XHTML Basic 1.0//EN" />
In Cocoon, the output is controlled by the "serializer" (the last step of the pipeline).
Some serializers are already defined:
Other serializers are easy to define and use:
Define in map:serializers in map:components
<map:serializer name="xhtml10basic"
src="org.apache.cocoon.serialization.XMLSerializer"
mime-type="application/xhtml+xml">
<doctype-public>-//W3C//DTD XHTML Basic 1.0//EN</doctype-public>
<doctype-system>http://www.w3.org/TR/xhtml-basic/xhtml-basic10.dtd</doctype-system>
<encoding>UTF-8</encoding>
<indent>yes</indent>
</map:serializer>We could define two serializers in Cocoon -- one for XHTML 1.0 Transitional, and the other for XHTML 1.0 Strict. In the pipeline, we would simply call the seriazlier that we desired.
Serializers defined:
<map:serializers>
<map:serializer name="xhtmlt"
src="org.apache.cocoon.serialization.XMLSerializer"
mime-type="text/html">
<doctype-public>-//W3C//DTD XHTML 1.0 Transitional//EN</doctype-public>
<doctype-system>http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd</doctype-system>
<encoding>UTF-8</encoding>
<indent>yes</indent>
</map:serializer>
<map:serializer name="xhtmls"
src="org.apache.cocoon.serialization.XMLSerializer"
mime-type="text/html">
<doctype-public>-//W3C//DTD XHTML 1.0 Strict//EN</doctype-public>
<doctype-system>http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd</doctype-system>
<encoding>UTF-8</encoding>
<indent>yes</indent>
</map:serializer>
</map:serializers>
Serializer used:
<map:match pattern="rss.html"> <map:generate src="rss.xml" type="file"/> <map:transform src="xsl/rss2html.xsl" type="xslt"/> <map:serialize type="xhtmlt"/> </map:match>