The entire example report up until this point has been nice with a cool feature or two but terribly unrealistic. It is important to have the data in mind when creating the form but the form that I have created is not good for much more than a simple laundry list.
The sixth example result will generate a form and will look like this.
The big change for this step is that rather than having a single set of data where all the items are identical, I slightly have changed the data structure to support multiple lists.
<xmlroottag> <beings> <listtype>presidents </listtype> <being> <first> Robert </first> <last> Kennedy </last> <party> Dem </party> </being> <being> <first> George </first> <last> Bush </last> <party> Rep </party> </being> ... </beings> <beings> <listtype>Rock Stars </listtype> <being> <first> Dave </first> <last> Chappelle </last> <party> Yup </party> </being> <being> <first> Rod </first> <last> Stewart </last> <party> Yup </party> </being> <being> <first> Izzy </first> <last> Stradlin </last> <party> Ya </party> </being> ... </beings> </xmlroottag>
Most of the xslt script remains the same when compared to the previous step. The difference is that we have a template for beings. This makes it really easy to create our table. The table should be full of records of type being and we have a template for generating each being. Thus we simply move the table declaration in to the beings template.
The only non-obvious part of this is why is there an apply-templates? The purpose of this is identical to the apply-templates in the region-body. It will start from the current position and for each xslt object at that level will evaluated against the existing templates.
Thus we have the apply-templates in the region body to cause the “beings” template to be executed (for each group of beings) and once we are in the beings template, the apply-templates causes each xslt object to be evaluated with the existing templates. This is what causes each being to be processed with the being template.
<xsl:template match="beings"> <fo:block font-size="16pt" font-weight="bold" space-after="2mm" space-before="5mm" >List of <xsl:value-of select="listtype"/> </fo:block> <fo:block font-size="10pt"> <fo:table table-layout="fixed" width="8cm"> <fo:table-column column-width="proportional-column-width(70)" /> <fo:table-column column-width="proportional-column-width(30)" /> <fo:table-header> <fo:table-row > <fo:table-cell border-collapse="collapse" border-style="solid" border-width=".1mm" text-align="left" > <fo:block font-size="10pt" font-weight="bold" background-color="lightgray" >Object</fo:block> </fo:table-cell> <fo:table-cell border-collapse="collapse" border-style="solid" border-width=".1mm" text-align="left" > <fo:block font-size="10pt" font-weight="bold" background-color="lightgray" >Attr.</fo:block> </fo:table-cell> </fo:table-row > </fo:table-header> <fo:table-body> <xsl:apply-templates /> </fo:table-body> </fo:table> <fo:block space-before="5mm"> thats all folks! </fo:block> </fo:block> </xsl:template>
The actual “being” records are all identical but they are all part of a beings structure. There are no limit to the number of “being” records but they are now all grouped together. Part of this group is the listtype field. So each group of beings could still be presidents or of different types of people or objects.
I have decided that the most natural fit would be to have a data file with both presidents and rock singers. How this looks actually is quite similar to the output in the previous step except that it is now possible to have an infinite number of beings in an infinite number of groups. Thus at a later point the program which creates this data file could add superheros or politicians without needing to amend the xslt script at all.
You need to either think a lot about this or look at the code to realize that there is now an additional listtype template. This template was created so the listtype element could be evaluated. When a template does not exist, then FOP will output the value. Having the listtype value randomly output to the form is not what is desired which is why the listtype template exists but doesn’t really contain a body. This was necessary because I needed the listtype value but I didn’t want to have a template to output the listtype.
Download source and pdf for this example
The next set of changes for this can be found in the final part.