Table of Contents

Contact Us or call 1-877-932-8228
Table of Contents

Table of Contents

Assume you have an XML document that contains a complete book that is divided into chapters. The table of contents will be created by taking a pass through the entire XML document, grabbing all the chapter titles and outputting those titles with page references. Generally, the title and page reference will be separated by some type of leader. The XSLT document below shows how the table of contents (shown above) was created.

Code Sample:

LeadersMarkers/Demos/Stories.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
	xmlns:fo="http://www.w3.org/1999/XSL/Format">
	<xsl:output method="xml" indent="yes"/>
	
	<xsl:template match="/">
		<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
			<fo:layout-master-set>
			
				<fo:simple-page-master master-name="TOC" 
					page-height="11in" page-width="8.5in" margin=".5in">
					<fo:region-body margin=".5in"/>
					<fo:region-before region-name="TocHead" extent=".5in"/>
					<fo:region-after region-name="TocFoot" extent=".5in"/>
				</fo:simple-page-master>
---- C O D E   O M I T T E D ----
</fo:layout-master-set>
			
			<fo:page-sequence master-reference="TOC" format="i">
			
				<fo:static-content flow-name="TocHead">
					<fo:block border-bottom-width="thin" border-bottom-style="solid" 
						border-bottom-color="green" font-weight="bold" text-align="outside">
						<xsl:text>Table of Contents</xsl:text>
					</fo:block>
				</fo:static-content>
				
				<fo:static-content flow-name="TocFoot">
					<fo:block border-bottom-width="thin" border-bottom-style="solid" 
						border-bottom-color="green" font-weight="bold" text-align="outside">
						<fo:page-number/>
					</fo:block>
				</fo:static-content>
				
				<fo:flow flow-name="xsl-region-body">
					<fo:block text-align="center" font-weight="bold" 
						font-size="larger">
						<xsl:text>Table of Contents</xsl:text>
					</fo:block>
					<xsl:apply-templates mode="TOC"/>
				</fo:flow>
				
			</fo:page-sequence>
			
			<fo:page-sequence master-reference="Stories" initial-page-number="1">
			
				<fo:static-content flow-name="oddHead">
					<fo:block border-bottom-width="thin" border-bottom-style="solid" 
						border-bottom-color="green" font-weight="bold" text-align="outside">
						<fo:retrieve-marker retrieve-class-name="StoryTitle"
							retrieve-position="first-including-carryover"/>
					</fo:block>
				</fo:static-content>
				
				<fo:static-content flow-name="evenHead">
					<fo:block border-bottom-width="thin" border-bottom-style="solid" 
						border-bottom-color="green" font-weight="bold" text-align="outside">
						<fo:retrieve-marker retrieve-class-name="StoryTitle"
							retrieve-position="first-including-carryover"/>
					</fo:block>
				</fo:static-content>
---- C O D E   O M I T T E D ----
</fo:page-sequence>
			
		</fo:root>
		
	</xsl:template>
	
	<xsl:template match="body/div/h2" mode="TOC">
		<fo:block font-size="smaller" space-after=".1in" 
			space-before=".15in" text-align-last="justify">
			<fo:basic-link internal-destination="{generate-id(.)}">
				<xsl:value-of select="."/>
				<fo:leader leader-pattern="dots"/>
				<fo:page-number-citation ref-id="{generate-id(.)}"/>
			</fo:basic-link>
		</fo:block>
	</xsl:template>
	
	<xsl:template match="body/div/h2" mode="Stories">
		<fo:block font-weight="bold" font-size="larger" 
			id="{generate-id(.)}" break-before="odd-page">
			<fo:marker marker-class-name="StoryTitle">
				<xsl:value-of select="."/>
			</fo:marker>
			<xsl:value-of select="."/>
		</fo:block>
	</xsl:template>
---- C O D E   O M I T T E D ----
</xsl:stylesheet>

Page Numbering

In the example above, there is a simple-page-master for the table of contents. There's nothing special about this page master. The page-sequence that references it is also pretty standard, with one exception. It has a format attribute, which specifies how page numbers should be formatted. In this case, it takes the value of "i", meaning lowercase Roman numerals will be used. Other options are "I", "A", "a", and "1" (the default).

In the following page-sequence FO, which contains the actual stories, we set the initial-page-number attribute to "1" to force the page count to start over. This page-sequence will use Arabic notation (the default) for page numbers, because the format attribute is left off.

page-number-citation

The page number itself is output with the page-number-citation FO, which uses generate-id() to reference the location at which that node appears in the document.

<fo:page-number-citation ref-id="{generate-id(.)}"/>
Next