- Sams Teach Yourself XML in 21 Days, Third Edition
- Table of Contents
- About the Author
- Acknowledgments
- We Want to Hear from You!
- Introduction
- Part I: At a Glance
- Day 1. Welcome to XML
- All About Markup Languages
- All About XML
- Looking at XML in a Browser
- Working with XML Data Yourself
- Structuring Your Data
- Creating Well-Formed XML Documents
- Creating Valid XML Documents
- How XML Is Used in the Real World
- Online XML Resources
- Summary
- Q&A
- Workshop
- Day 2. Creating XML Documents
- Choosing an XML Editor
- Using XML Browsers
- Using XML Validators
- Creating XML Documents Piece by Piece
- Creating Prologs
- Creating an XML Declaration
- Creating XML Comments
- Creating Processing Instructions
- Creating Tags and Elements
- Creating CDATA Sections
- Handling Entities
- Summary
- Q&A
- Workshop
- Day 3. Creating Well-Formed XML Documents
- What Makes an XML Document Well-Formed?
- Creating an Example XML Document
- Understanding the Well-Formedness Constraints
- Using XML Namespaces
- Understanding XML Infosets
- Understanding Canonical XML
- Summary
- Q&A
- Workshop
- Day 4. Creating Valid XML Documents: DTDs
- All About DTDs
- Validating a Document by Using a DTD
- Creating Element Content Models
- Commenting a DTD
- Supporting External DTDs
- Handling Namespaces in DTDs
- Summary
- Q&A
- Workshop
- Declaring Attributes in DTDs
- Day 5. Handling Attributes and Entities in DTDs
- Specifying Default Values
- Specifying Attribute Types
- Handling Entities
- Summary
- Q&A
- Workshop
- Day 6. Creating Valid XML Documents: XML Schemas
- Using XML Schema Tools
- Creating XML Schemas
- Dissecting an XML Schema
- The Built-in XML Schema Elements
- Creating Elements and Types
- Specifying a Number of Elements
- Specifying Element Default Values
- Creating Attributes
- Summary
- Q&A
- Workshop
- Day 7. Creating Types in XML Schemas
- Restricting Simple Types by Using XML Schema Facets
- Creating XML Schema Choices
- Using Anonymous Type Definitions
- Declaring Empty Elements
- Declaring Mixed-Content Elements
- Grouping Elements Together
- Grouping Attributes Together
- Declaring all Groups
- Handling Namespaces in Schemas
- Annotating an XML Schema
- Summary
- Q&A
- Workshop
- Part I. In Review
- Well-Formed Documents
- Valid Documents
- Part II: At a Glance
- Day 8. Formatting XML by Using Cascading Style Sheets
- Our Sample XML Document
- Introducing CSS
- Connecting CSS Style Sheets and XML Documents
- Creating Style Sheet Selectors
- Using Inline Styles
- Creating Style Rule Specifications in Style Sheets
- Summary
- Q&A
- Workshop
- Day 9. Formatting XML by Using XSLT
- Introducing XSLT
- Transforming XML by Using XSLT
- Writing XSLT Style Sheets
- Using <xsl:apply-templates>
- Using <xsl:value-of> and <xsl:for-each>
- Matching Nodes by Using the match Attribute
- Working with the select Attribute and XPath
- Using <xsl:copy>
- Using <xsl:if>
- Using <xsl:choose>
- Specifying the Output Document Type
- Summary
- Q&A
- Workshop
- Day 10. Working with XSL Formatting Objects
- Introducing XSL-FO
- Using XSL-FO
- Using XSL Formatting Objects and Properties
- Building an XSL-FO Document
- Handling Inline Formatting
- Formatting Lists
- Formatting Tables
- Summary
- Q&A
- Workshop
- Part II. In Review
- Using CSS
- Using XSLT
- Using XSL-FO
- Part III: At a Glance
- Day 11. Extending HTML with XHTML
- Why XHTML?
- Writing XHTML Documents
- Validating XHTML Documents
- The Basic XHTML Elements
- Organizing Text
- Formatting Text
- Selecting Fonts: <font>
- Comments: <!-->
- Summary
- Q&A
- Workshop
- Day 12. Putting XHTML to Work
- Creating Hyperlinks: <a>
- Linking to Other Documents: <link>
- Handling Images: <img>
- Creating Frame Documents: <frameset>
- Creating Frames: <frame>
- Creating Embedded Style Sheets: <style>
- Formatting Tables: <table>
- Creating Table Rows: <tr>
- Formatting Table Headers: <th>
- Formatting Table Data: <td>
- Extending XHTML
- Summary
- Q&A
- Workshop
- Day 13. Creating Graphics and Multimedia: SVG and SMIL
- Introducing SVG
- Creating an SVG Document
- Creating Rectangles
- Adobe's SVG Viewer
- Using CSS Styles
- Creating Circles
- Creating Ellipses
- Creating Lines
- Creating Polylines
- Creating Polygons
- Creating Text
- Creating Gradients
- Creating Paths
- Creating Text Paths
- Creating Groups and Transformations
- Creating Animation
- Creating Links
- Creating Scripts
- Embedding SVG in HTML
- Introducing SMIL
- Summary
- Q&A
- Workshop
- Day 14. Handling XLinks, XPointers, and XForms
- Introducing XLinks
- Beyond Simple XLinks
- Introducing XPointers
- Introducing XBase
- Introducing XForms
- Summary
- Workshop
- Part III. In Review
- Part IV: At a Glance
- Day 15. Using JavaScript and XML
- Introducing the W3C DOM
- Introducing the DOM Objects
- Working with the XML DOM in JavaScript
- Searching for Elements by Name
- Reading Attribute Values
- Getting All XML Data from a Document
- Validating XML Documents by Using DTDs
- Summary
- Q&A
- Workshop
- Day 16. Using Java and .NET: DOM
- Using Java to Read XML Data
- Finding Elements by Name
- Creating an XML Browser by Using Java
- Navigating Through XML Documents
- Writing XML by Using Java
- Summary
- Q&A
- Workshop
- Day 17. Using Java and .NET: SAX
- An Overview of SAX
- Using SAX
- Using SAX to Find Elements by Name
- Creating an XML Browser by Using Java and SAX
- Navigating Through XML Documents by Using SAX
- Writing XML by Using Java and SAX
- Summary
- Q&A
- Workshop
- Day 18. Working with SOAP and RDF
- Introducing SOAP
- A SOAP Example in .NET
- A SOAP Example in Java
- Introducing RDF
- Summary
- Q&A
- Workshop
- Part IV. In Review
- Part V: At a Glance
- Day 19. Handling XML Data Binding
- Introducing DSOs
- Binding HTML Elements to HTML Data
- Binding HTML Elements to XML Data
- Binding HTML Tables to XML Data
- Accessing Individual Data Fields
- Binding HTML Elements to XML Data by Using the XML DSO
- Binding HTML Tables to XML Data by Using the XML DSO
- Searching XML Data by Using a DSO and JavaScript
- Handling Hierarchical XML Data
- Summary
- Q&A
- Workshop
- Day 20. Working with XML and Databases
- XML, Databases, and ASP
- Storing Databases as XML
- Using XPath with a Database
- Introducing XQuery
- Summary
- Q&A
- Workshop
- Day 21. Handling XML in .NET
- Creating and Editing an XML Document in .NET
- From XML to Databases and Back
- Reading and Writing XML in .NET Code
- Using XML Controls to Display Formatted XML
- Creating XML Web Services
- Summary
- Q&A
- Workshop
- Part V. In Review
- Appendix A. Quiz Answers
- Quiz Answers for Day 1
- Quiz Answers for Day 2
- Quiz Answers for Day 3
- Quiz Answers for Day 4
- Quiz Answers for Day 5
- Quiz Answers for Day 6
- Quiz Answers for Day 7
- Quiz Answers for Day 8
- Quiz Answers for Day 9
- Quiz Answers for Day 10
- Quiz Answers for Day 11
- Quiz Answers for Day 12
- Quiz Answers for Day 13
- Quiz Answers for Day 14
- Quiz Answers for Day 15
- Quiz Answers for Day 16
- Quiz Answers for Day 17
- Quiz Answers for Day 18
- Quiz Answers for Day 19
- Quiz Answers for Day 20
- Quiz Answers for Day 21
Using XSL-FO
You've already seen a short XSL-FO example, but in fact, XML documents are only rarely formatted by directly using formatting objects as in the example you've seen because the process becomes too complex. What usually happens is that you take an XML document (with the extension .xml), run it through an XSLT processor to create a new XML document that uses XSL-FO (with the extension .fo), and then use an XSL-FO processor to create the formatted display document (with the extension .pdf in today's discussion). You do things this way because any document except a nontrivial one has many paragraphs of text or data, and to format each one by hand would be a time-consuming process.
In fact, XSLT was originally developed for formatting XML documents by using XSL-FO objects. Since then, being able to access XML data without writing software using XSLT in itself has become so powerful that XSLT has outstripped XSL-FO in popularity.
For example, say that you want to use XSL-FO to format the XML document with state data that you worked with yesterday. Let's use that document today, renaming it ch10_01.xml, as shown in Listing 10.1.
Example 10.1. An Example of an XML Document (ch10_01.xml)
<?xml version="1.0" encoding ="UTF-8"?> <states> <state> <name>California</name> <population units="people">33871648</population><!--2000 census--> <capital>Sacramento</capital> <bird>Quail</bird> <flower>Golden Poppy</flower> <area units="square miles">155959</area> </state> <state> <name>Massachusetts</name> <population units="people">6349097</population><!--2000 census--> <capital>Boston</capital> <bird>Chickadee</bird> <flower>Mayflower</flower> <area units="square miles">7840</area> </state> <state> <name>New York</name> <population units="people">18976457</population><!--2000 census--> <capital>Albany</capital> <bird>Bluebird</bird> <flower>Rose</flower> <area units="square miles">47214</area> </state> </states>
As you'll see later today, the XSL-FO document holding this data that you're going to feed into an XSL-FO processor is about three times the length of ch10_01.xml, which is why it makes sense to use XSLT to convert ch10_01.xml into a document that uses XSL-FO. Let's take a look at the XSLT style sheet that will do that.
Using XSLT to Create an XSL-FO Document
Although you could format ch10_01.xml by hand, it's easier to use an XSLT style sheet to do so. Listing 10.2 contains the style sheet (ch10_02.xml) that you're going to use in this example. In this case, you're just going to extract the state data from ch10_01.xml and present that data in a list form, using 18-point font.
Example 10.2. An XSL Document That Adds XSL-FO Formatting (ch10_02.xsl)
<?xml version='1.0'?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" version='1.0'> <xsl:template match="states"> <fo:root> <fo:layout-master-set> <fo:simple-page-master master-name="mainPage" page-height="300mm" page-width="200mm" margin-top="20mm" margin-bottom="20mm" margin-left="20mm" margin-right="20mm"> <fo:region-body margin-top="0mm" margin-bottom="10mm" margin-left="0mm" margin-right="0mm"/> <fo:region-after extent="20mm"/> </fo:simple-page-master> </fo:layout-master-set> <fo:page-sequence master-reference="mainPage"> <fo:flow flow-name="xsl-region-body"> <xsl:apply-templates/> </fo:flow> </fo:page-sequence> </fo:root> </xsl:template> <xsl:template match="state/name"> <fo:block font-weight="bold" font-size="18pt" line-height="24pt" font-family="sans-serif" text-decoration="underline"> Name: <xsl:value-of select="."/> </fo:block> </xsl:template> <xsl:template match="state/population"> <fo:block font-size="18pt" line-height="24pt" font-family="sans-serif"> Population (people): <xsl:value-of select="."/> </fo:block> </xsl:template> <xsl:template match="state/capital"> <fo:block font-size="18pt" line-height="24pt" font-family="sans-serif"> Capital: <xsl:value-of select="."/> </fo:block> </xsl:template> <xsl:template match="state/bird"> <fo:block font-size="18pt" line-height="24pt" font-family="sans-serif"> Bird: <xsl:value-of select="."/> </fo:block> </xsl:template> <xsl:template match="state/flower"> <fo:block font-size="18pt" line-height="24pt" font-family="sans-serif"> Flower: <xsl:value-of select="."/> </fo:block> </xsl:template> <xsl:template match="state/area"> <fo:block font-size="18pt" line-height="24pt" font-family="sans-serif"> Area (square miles): <xsl:value-of select="."/> </fo:block> </xsl:template> </xsl:stylesheet>
Today you'll see how ch10_02.xsl works and what it does. The first step, as described in the following section, is to put this style sheet to work and create the XSL-FO document.
Creating an XSL-FO Document by Using an XSLT Style Sheet
You're ready to create an XSL-FO document, which you can call ch10_03.fo. This document is the one you'll feed into an XSL-FO processor to create a formatted PDF document that will display the data from the XML document ch10_01.xml. To create ch10_03.fo, you only need to apply the XSLT style sheet ch10_02.xsl to the XML document ch10_01.xml. For example, if you have Java 1.4 or later installed, you can use the Java file ch09_05.class that is in the code download area for this book that you used yesterday, like this:
%java ch09_05 ch10_01.xml ch10_02.xsl ch10_03.fo
This creates ch10_03.fo, which is ch10_01.xml formatted with XSL-FO. Listing 10.3 presents ch10_03.fo; note the length of it compared to the original XML document, ch10_01.xml, and you can see why it's a good idea to use XSLT to create XSL-FO documents if you're working with data of any significant length.
Example 10.3. An XSL-FO Document (ch10_03.fo)
<?xml version="1.0" encoding="UTF-8"?> <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> <fo:layout-master-set> <fo:simple-page-master margin-right="20mm" margin-left="20mm" margin-bottom="20mm" margin-top="20mm" page-width="200mm" page-height="300mm" master-name="mainPage"> <fo:region-body margin-right="0mm" margin-left="0mm" margin-bottom="10mm" margin-top="0mm"/> <fo:region-after extent="20mm"/> </fo:simple-page-master> </fo:layout-master-set> <fo:page-sequence master-reference="mainPage"> <fo:flow flow-name="xsl-region-body"> <fo:block text-decoration="underline" font-family="sans-serif" line-height="24pt" font-size="18pt" font-weight="bold"> Name: California </fo:block> <fo:block font-family="sans-serif" line-height="24pt" font-size="18pt"> Population (people): 33871648 </fo:block> <fo:block font-family="sans-serif" line-height="24pt" font-size="18pt"> Capital: Sacramento </fo:block> <fo:block font-family="sans-serif" line-height="24pt" font-size="18pt"> Bird: Quail </fo:block> <fo:block font-family="sans-serif" line-height="24pt" font-size="18pt"> Flower: Golden Poppy </fo:block> <fo:block font-family="sans-serif" line-height="24pt" font-size="18pt"> Area (square miles) : 155959 </fo:block> <fo:block text-decoration="underline" font-family="sans-serif" line-height="24pt" font-size="18pt" font-weight="bold"> Name: Massachusetts </fo:block> <fo:block font-family="sans-serif" line-height="24pt" font-size="18pt"> Population (people): 6349097 </fo:block> <fo:block font-family="sans-serif" line-height="24pt" font-size="18pt"> Capital: Boston </fo:block> <fo:block font-family="sans-serif" line-height="24pt" font-size="18pt"> Bird: Chickadee </fo:block> <fo:block font-family="sans-serif" line-height="24pt" font-size="18pt"> Flower: Mayflower </fo:block> <fo:block font-family="sans-serif" line-height="24pt" font-size="18pt"> Area (square miles): 7840 </fo:block> <fo:block text-decoration="underline" font-family="sans-serif" line-height="24pt" font-size="18pt" font-weight="bold"> Name: New York </fo:block> <fo:block font-family="sans-serif" line-height="24pt" font-size="18pt"> Population (people): 18976457 </fo:block> <fo:block font-family="sans-serif" line-height="24pt" font-size="18pt"> Capital: Albany </fo:block> <fo:block font-family="sans-serif" line-height="24pt" font-size="18pt"> Bird: Bluebird </fo:block> <fo:block font-family="sans-serif" line-height="24pt" font-size="18pt"> Flower: Rose </fo:block> <fo:block font-family="sans-serif" line-height="24pt" font-size="18pt"> Area (square miles): 47214 </fo:block> </fo:flow> </fo:page-sequence> </fo:root>
You now have ch10_03.fo, which is ready to feed into an XSL-FO processor.
Creating a PDF Document
To use ch10_03.fo and convert it into a PDF file, ch10_04.pdf, you can use what is probably the most popular XSL-FO processor, the Apache XML Project's FOP. You can get FOP for free at http://xml.apache.org/fop; just click the Download button. The current version as of this writing is 0.20.4 (0.20.5 is available in a release candidate version, but it's not yet official), and it's written in Java, which means you have to have Java installed in order to use it. The compressed file you download is fop-0.20.4-bin.tar.gz. (.tar.gz files are targeted to Unix, but Windows unzip utilities, such as WinZip, from http://www.winzip.com, can unzip them as well.)
Here's how to use FOP to convert ch10_03.fo into ch10_04.pdf, assuming that ch10_03.fo is in the same directory where you unzipped FOP (the -cp switch here sets the Java classpath variable, which you'll discuss further on Day 16, "Using Java and .NET: DOM"):
%java -cp build\fop.jar;lib\batik.jar;lib\xalan-2.3.1.jar; lib\xercesImpl-2.0.1.jar;lib\xml-apis.jar; lib\avalon-framework-cvs-20020315.jar;lib\logkit-1.0.jar; lib\jimi-1.0.jar org.apache.fop.apps.Fop ch10_03.fo ch10_04.pdf
This is not very easy to type, so FOP also supplies shell scripts for most shells, including a .bat file for Windows, which means that the following is usually all you have to type:
%fop ch10_03.fo ch10_04.pdf
This creates ch10_04.pdf, which is the goal you've been working toward. To view this PDF document, you can use the Adobe Acrobat PDF viewer, which you can download for free from Adobe at http://www.adobe.com (currently, Adobe Acrobat reader is available at http://www.adobe.com/products/acrobat/readermain.html). Figure 10.1 shows ch10_04.pdf in Adobe Acrobat. As you can see in the figure, the data from the XML document has indeed been formatted into a PDF document.
Figure 10.1 Formatting XML data in PDF format.
Now take a look at how to create your own XSL-FO formatting.