[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Tweaking XSL to preserve line breaks for XSL:FO using Apache FOP

Posted on 2010-01-07
3
Medium Priority
?
1,832 Views
Last Modified: 2013-11-18
I am a relative XSLT neophyte who is taking the plunge into XSL:FO using Apache FOP.  I've managed to figure out headers, footers, mixing single and double-column layout on the same page, and a few other goodies.  One last thing is holding me back -- preserving line breaks in the source data.  Attached are sample XML and XSL files that illustrate my problem.  The <data> section is populated by the application, and as you can see in the example, this particular PAYMENT_SCHEDULE has embedded line breaks.  (There are other fields with similar requirements, so please don't tell me to reformat the payment schedule.)

From Googling, I know that each line must somehow be wrapped in a <fo:block> tag in order to preserve the line breaks, but I just can't seem to figure out how to do it.  If you can show me how to fix this sample either by modifying the contents of the <field name="PAYMENT_SCHEDULE"> tag or by modifying the XSL file, I would greatly appreciate it!  Thank you in advance!
Sample.xml:

<?xml version="1.0" encoding="UTF-8"?>
<document>
  <data>
    <row>
      <field name="COMPANY">Acme Rocket Sleds, LLC</field>
      <field name="DOCUMENT_NUMBER">12345</field>
      <field name="AMOUNT_FINANCED">$ 50,000.00</field>
      <field name="PAYMENT_SCHEDULE">5 Quarterly payments, plus any applicable taxes, payable in advance as follows:
    1 - 1 : $35,000.00
    2 - 5 : $8.552.07</field>
      <field name="COMMENCEMENT_DATE">January 1, 2010</field>
    </row>
  </data>

  <content>
    <contract-header/>
  </content>
      
</document>


Sample.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:template match="/">
 
 <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
 
   <fo:layout-master-set>

       <fo:simple-page-master page-height="11in" page-width="8.5in" master-name="only">
         <fo:region-body region-name="xsl-region-body" margin="0.7in"/>
         <fo:region-before extent="0.7in"/>
         <fo:region-after extent="0.7in"/>
       </fo:simple-page-master>
   </fo:layout-master-set>

   <fo:page-sequence master-reference="only">
       <fo:flow flow-name="xsl-region-body">
          <xsl:apply-templates select="document/content"/>
       </fo:flow>
   </fo:page-sequence>

 </fo:root> 
 </xsl:template>
 
 <xsl:template match="content">
       <xsl:apply-templates/>
 </xsl:template>

 <xsl:template match="contract-header">
       <fo:block id="Contract Header" span="all" font-family="serif" font-size="9pt">
       <fo:table border="1.5pt solid black" border-spacing="2pt" table-layout="fixed" width="100%">
         <fo:table-column column-width="25%"/>
         <fo:table-column column-width="35%"/>
         <fo:table-column column-width="6%"/>
         <fo:table-column column-width="34%"/>
         <fo:table-body>
           <fo:table-row>
             <fo:table-cell border="0.5pt solid black">
               <fo:block>Contract #:</fo:block>
             </fo:table-cell>
             <fo:table-cell border="0.5pt solid black">
               <fo:block font-weight="bold"><xsl:value-of select="/document/data/row/field[@name='DOCUMENT_NUMBER']"/></fo:block>
             </fo:table-cell>
             <fo:table-cell border="0.5pt solid black">
               <fo:block>Dated:</fo:block>
             </fo:table-cell>
             <fo:table-cell border="0.5pt solid black">
               <fo:block font-weight="bold"><xsl:value-of select="/document/data/row/field[@name='COMMENCEMENT_DATE']"/></fo:block>
             </fo:table-cell>
           </fo:table-row>
           <fo:table-row>
             <fo:table-cell border="0.5pt solid black">
               <fo:block>Company:</fo:block>
             </fo:table-cell>
             <fo:table-cell border="0.5pt solid black" number-columns-spanned="3">
               <fo:block font-weight="bold">
                 <xsl:value-of select="/document/data/row/field[@name='COMPANY']"/>
               </fo:block>
             </fo:table-cell>
           </fo:table-row>
           <fo:table-row>
             <fo:table-cell border="0.5pt solid black">
               <fo:block>Original Cost and Fees of Products:</fo:block>
             </fo:table-cell>
             <fo:table-cell border="0.5pt solid black" number-columns-spanned="3">
               <fo:block><xsl:value-of select="/document/data/row/field[@name='AMOUNT_FINANCED']"/></fo:block>
             </fo:table-cell>
           </fo:table-row>
           <fo:table-row>
             <fo:table-cell border="0.5pt solid black">
               <fo:block>Payments due under this IPA:</fo:block>
             </fo:table-cell>
             <fo:table-cell border="0.5pt solid black" number-columns-spanned="3">
               <fo:block><xsl:value-of select="/document/data/row/field[@name='PAYMENT_SCHEDULE']"/></fo:block>
             </fo:table-cell>
           </fo:table-row>
           <fo:table-row>
             <fo:table-cell border="0.5pt solid black">
               <fo:block>Guarantor (if any):</fo:block>
             </fo:table-cell>
             <fo:table-cell border="0.5pt solid black" number-columns-spanned="3">
               <fo:block></fo:block>
             </fo:table-cell>
           </fo:table-row>
         </fo:table-body>
       </fo:table>
       </fo:block>
 </xsl:template>
 
 </xsl:stylesheet>

Open in new window

0
Comment
Question by:arktech
  • 2
3 Comments
 
LVL 60

Accepted Solution

by:
Geert Bormans earned 2000 total points
ID: 26353916
Hey, sounds like you can use a recursive function to get all the new-lines and create blocks
<?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 indent="yes"/>
    <xsl:template match="/"> 
        
        <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> 
            
            <fo:layout-master-set> 
                
                <fo:simple-page-master page-height="11in" page-width="8.5in" master-name="only"> 
                    <fo:region-body region-name="xsl-region-body" margin="0.7in"/> 
                    <fo:region-before extent="0.7in"/> 
                    <fo:region-after extent="0.7in"/> 
                </fo:simple-page-master> 
            </fo:layout-master-set> 
            
            <fo:page-sequence master-reference="only"> 
                <fo:flow flow-name="xsl-region-body"> 
                    <xsl:apply-templates select="document/content"/> 
                </fo:flow> 
            </fo:page-sequence> 
            
        </fo:root>  
    </xsl:template> 
    
    <xsl:template match="content"> 
        <xsl:apply-templates/> 
    </xsl:template> 
    
    <xsl:template match="contract-header"> 
        <fo:block id="Contract Header" span="all" font-family="serif" font-size="9pt"> 
            <fo:table border="1.5pt solid black" border-spacing="2pt" table-layout="fixed" width="100%"> 
                <fo:table-column column-width="25%"/> 
                <fo:table-column column-width="35%"/> 
                <fo:table-column column-width="6%"/> 
                <fo:table-column column-width="34%"/> 
                <fo:table-body> 
                    <fo:table-row> 
                        <fo:table-cell border="0.5pt solid black"> 
                            <fo:block>Contract #:</fo:block> 
                        </fo:table-cell> 
                        <fo:table-cell border="0.5pt solid black"> 
                            <fo:block font-weight="bold"><xsl:value-of select="/document/data/row/field[@name='DOCUMENT_NUMBER']"/></fo:block> 
                        </fo:table-cell> 
                        <fo:table-cell border="0.5pt solid black"> 
                            <fo:block>Dated:</fo:block> 
                        </fo:table-cell> 
                        <fo:table-cell border="0.5pt solid black"> 
                            <fo:block font-weight="bold"><xsl:value-of select="/document/data/row/field[@name='COMMENCEMENT_DATE']"/></fo:block> 
                        </fo:table-cell> 
                    </fo:table-row> 
                    <fo:table-row> 
                        <fo:table-cell border="0.5pt solid black"> 
                            <fo:block>Company:</fo:block> 
                        </fo:table-cell> 
                        <fo:table-cell border="0.5pt solid black" number-columns-spanned="3"> 
                            <fo:block font-weight="bold"> 
                                <xsl:value-of select="/document/data/row/field[@name='COMPANY']"/> 
                            </fo:block> 
                        </fo:table-cell> 
                    </fo:table-row> 
                    <fo:table-row> 
                        <fo:table-cell border="0.5pt solid black"> 
                            <fo:block>Original Cost and Fees of Products:</fo:block> 
                        </fo:table-cell> 
                        <fo:table-cell border="0.5pt solid black" number-columns-spanned="3"> 
                            <fo:block><xsl:value-of select="/document/data/row/field[@name='AMOUNT_FINANCED']"/></fo:block> 
                        </fo:table-cell> 
                    </fo:table-row> 
                    <fo:table-row> 
                        <fo:table-cell border="0.5pt solid black"> 
                            <fo:block>Payments due under this IPA:</fo:block> 
                        </fo:table-cell> 
                        <fo:table-cell border="0.5pt solid black" number-columns-spanned="3"> 
                            <xsl:call-template name="replace-new-line">
                                <xsl:with-param name="str" select="/document/data/row/field[@name='PAYMENT_SCHEDULE']"/>
                            </xsl:call-template>
                        </fo:table-cell> 
                    </fo:table-row> 
                    <fo:table-row> 
                        <fo:table-cell border="0.5pt solid black"> 
                            <fo:block>Guarantor (if any):</fo:block> 
                        </fo:table-cell> 
                        <fo:table-cell border="0.5pt solid black" number-columns-spanned="3"> 
                            <fo:block></fo:block> 
                        </fo:table-cell> 
                    </fo:table-row> 
                </fo:table-body> 
            </fo:table> 
        </fo:block> 
    </xsl:template> 
    
    <xsl:template name="replace-new-line">
        <xsl:param name="str"/>
        <xsl:choose>
            <xsl:when test="contains($str, '&#10;')">
                <fo:block>
                    <xsl:value-of select="normalize-space(substring-before($str, '&#10;'))"/>
                </fo:block>
                <xsl:call-template name="replace-new-line">
                    <xsl:with-param name="str" select="substring-after($str, '&#10;')"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <fo:block>
                    <xsl:value-of select="normalize-space($str)"/>
                </fo:block>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

Open in new window

0
 

Author Closing Comment

by:arktech
ID: 31674024
Perfect!  That is exactly the type of solution I was hoping for!  Great answer, Gertone!
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 26354654
welcome
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article covers the basics of the Sass, which is a CSS extension language. You will learn about variables, mixins, and nesting.
Without even knowing it, most of us are using web applications on a daily basis.  In fact, Gmail and Yahoo email, Twitter, Facebook, and eBay are used by most of us daily—and they are web applications. We generally confuse these web applications to…
The viewer will learn how to dynamically set the form action using jQuery.
Video by: Mark
This lesson goes over how to construct ordered and unordered lists and how to create hyperlinks.
Suggested Courses

872 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question