|
Comments
Did you read today's front page stories & breaking news?
SYS-CON.TV
|
XML Protocols Statements on Demand Using XSL-FO
Statements on Demand Using XSL-FO
By: Douglas Lovell
Apr. 29, 2003 12:00 AM
We encounter many statements and reports in our day-to-day lives. Phone bills, utility bills, bank statements, and investment account statements are a few examples. More and more, the companies that produce these statements are making them available online, on demand through the Web. Some companies now offer incentives for customers to accept online statements in lieu of printed statements delivered through the mail; customers who want a printed record must print it locally. The problem with printing locally is that statements produced as HTML don't print well. The page breaks don't occur in the right place - table footers appear at the top of the page following where they should appear, and lines of text split from one page to the next. The edges of the reports get truncated on the printer such that all of the account detail on the right-hand side is lost. A much better format for presenting statements online, from the perspective of print, is PDF, Adobe's document format that has been widely adopted for typeset-quality presentation on the Web. Implementations of the XSL standards make it relatively simple to produce online account statements on demand as PDFs, with quality equaling that of statements that are printed and sent via mail. The benefit to vendors is that they may produce statements using the same technology for print and for online delivery. IBM now sells a product for producing AFP, a print format that drives the high-speed printers typically used to print statements for mass mailing, from FO. Using a single transform for both online and print presentation reduces development and maintenance costs and ensures consistency. Customers benefit by receiving PDF documents that they can store for later review or print with quality approaching that of statements they're accustomed to receiving in the mail. This article demonstrates the capability for generating statements online as PDF by implementing a real-world example. The example statement is an investor account summary from an IRA. As they used to say on "Perry Mason," the names have been changed to protect the innocent. The first stage of implementation is to write a back-end routine that accepts the customer query and produces an XML-encoded representation of the result. This is at least half of the work, but it's the same work any report generator producing the final formatted report would have to do. The advantage of producing an XML document as the end product of this step is that now all the logic for styling and presenting the content is separate from the logic needed to fetch it. A change to the report format will not necessarily entail digging into code that both fetches and formats the data. XML decouples data fetching from data formatting. One major decision that arises when preparing the XML that will drive a report is whether to include summary and calculated information. Including summary information moves computation to the back-end process that makes the database queries and produces the XML. Excluding summary information moves computation to the transform process that styles and presents the data. Some forms of computation may be easier or more efficient when done by the SQL engine or programming logic than when done with the transform. The transform engine may do simple subtotals, but computations such as market value, yield, or asset percentages might best be done with the back-end logic. One way to tackle a formatting task like this one is to use a top-down approach. Start with the overall layout and structure of the document and work down into the details of each section. The main challenge is to ensure that the content of each section ends up inside an fo:block, where text is allowed. Listing 1 provides the first coarse cut. It provides the page layout, section headers, and block elements for the text. Account information appears in a static header region that will repeat at the top of each page. The body of the statement contains transaction and summary information. Figure 1 illustrates the first intermediate result. It doesn't look particularly well formatted at this point, but it runs. It's a start - it's something that works, that you can refine. You can apply two forms of refinement when incrementally developing a stylesheet: structural refinements and refinements of style. Structure refers to the basic elements and their nesting, one within another. Style refers to the properties that control visual elements such as color, font, borders, and spacing. The first refinement of style is to separate it from the structure using some of the code reuse and modularization mechanisms of XSL - the named attribute set and the included file. The stylesheet in its final form, statement.xsl, uses the XSL include mechanism to bring in style attribute set definitions from the file, statement.style.xsl (see Listings 3 and 4; the complete code listings for this article are available at www.sys-con.com/xml/sourcec.cfm). Naming and separating style attributes in this way has a number of benefits. First, it helps make more evident the structure of the result document from a reading of the stylesheet. The structure is clearer because it isn't interlaced with lots of properties to affect the style. Second, separation of the style elements allows a separation of concerns. A graphic designer or layout artist can work on the style attributes to affect a pleasing appearance without having to meddle with the more algorithmic, programming-oriented structural transform component of the stylesheet. Finally, using named attribute sets ensures consistency whenever the stylesheet calls upon them from more than one place. The primary structural refinements to the initial stylesheet work to wrestle the transaction and summary data into tabular form. Writing XSL templates to produce tables requires attention to a number of details. First there is the structure of the table - the division of data into cells within rows and columns. Then there are table headers and footers; column widths; table, cell, row, and column borders; and alignments; all of which must be just right before the stylesheet yields a presentable result. There are a number of tricks that will help you get a grip on the table output of your stylesheet. The first is to set aside the computer keyboard and make a sketch. The sketch does not have to look exactly like the result table, but it should clearly show the structure. Mark off columns and label them with their headers. Write the names of the elements that will appear in each column. This sketch will help you keep the overall structure as a reference while you navigate the details of writing the table layout. The sketch shown in Figure 2 is an example. With the sketch as a guide you can quickly fill in the basic structure of the result table. The coding for the transactions table, for example, consists of a template to match the transaction-list element paired with a template that matches each transaction element. The template that matches the transaction list outputs the table itself. The template that matches the transactions outputs one table row per transaction. Listing 2 shows the way the code appears in its initial, rough form. This gets you started quickly, and very nicely, with the structure of the table. Now you can add the table header and footer in the base template, the one that generates the table. After that you can add column definitions, then tweak the cell alignments, borders, and so forth to get an acceptable looking report. Listing 3 gives the fully developed stylesheet and Figure 3 shows the result. You may gain a lot of insight about how to make things work with XSL by studying the stylesheet available for download from the XML-J Web site. The transaction summary portion of the stylesheet demonstrates a few tricks in particular. First, the table layout attribute set omits table footers at line breaks. This prevents the summary total from appearing at the bottom of the first page, before the report has shown all of the transactions. First, the stylesheet uses the sum() function. Cells that contain dollar amounts call the format-dollar-amount template to get separators at multiples of one thousand and to always print trailing zeros to show hundredths of a dollar. The format-dollar-amount template uses the format-number() function of XSL. The quantity column of the mutual funds table uses the format-number() function as well. One difficult problem with the transactions table is to get a continuation indicator into the table header when the table prints across a page break. The use of the FO marker and retrieve-marker elements should solve this problem. The FO implementation used to produce the PDF may not support the marker element. The idea is to retrieve the marker in the header. When the header outputs for the first time the marker is empty. Table rows define the marker with the continuation text. When the header prints on subsequent pages it should contain the redefined continuation marker. The last trick in the transactions table is the method used to retrieve the text for the description column. The template first defines a variable for that cell, named acctID, that contains the value of the ID attribute on the account. The expression, <xsl:value-of select="//stake[@id=$acctID]/name"/> retrieves the name of the account from the stake element earlier in the report. It would also be reasonable to read this information from a separate document using the document() function. The separate document would contain name, type, and other information about various investment offerings indexed by their identifiers.
Conclusion
Resources Reader Feedback: Page 1 of 1
Latest Cloud Developer Stories
Subscribe to the World's Most Powerful Newsletters
Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
|
SYS-CON Featured Whitepapers
Most Read This Week
Breaking Cloud Computing News
|
|||||||||||||||||||||||||||||||||||||||||||||||||