• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 345
  • Last Modified:

Displaying Repeating XML Data Outside Of A Table

I posted something similar to this yesterday but this is a slightly different question.

I have a simple XML document:

<?xml version="1.0" standalone="yes"?>
<Header>My Title</Header>
<Names>
   <Name>
      <First>Jim</First>
      <Last>Smith</Last>
   </Name>
   <Name>
      <First>Jim2</First>
      <Last>Smith2</Last>
   </Name>
   <Name>
      <First>Jim3</First>
      <Last>Smith3</Last>
   </Name>
</Names>
<Footer>My Footer</Footer>

Open in new window


All I want to do is have an XSLT document that will present this information as follows (shown below between the "===" lines):

======================
My Header

Jim                                    Jim2                              Jim3
Smith                                Smith2                          Smith3

My Footer
======================

Can someone provide the SIMPLEST XLST for this? I will be using the XSLT to transform the data into a Formatting Object (FO). While I do not think this would affect the XSLT, please let me know if I need to provide any other information. I'm just looking for a way to repeat the "Name" elements and list them across. Ideally I do not want to use any tables--I want the flexibility to present the 3 columns shown above in my own format. In other words, I want to have a block that contains the FirstName and LastName (as shown) and I want three of those blocks presented in order in a single row.

I would appreciate any assistance.

Regards,
Jon500
0
Jon500
Asked:
Jon500
  • 3
1 Solution
 
Geert BormansCommented:
Try this, it makes HTML out of it,
but you very easily replace this with some formatting object code afterwards
(only literals have to change, no logic)
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     version="1.0">
    <xsl:template match="/">
        <html>
            <body>
                <xsl:apply-templates select="*/*"/>
            </body>
        </html>
    </xsl:template>
    <xsl:template match="Header">
        <p>======================================</p>
        <p><xsl:value-of select="."/></p>
    </xsl:template>
    <xsl:template match="Footer">
        <p><xsl:value-of select="."/></p>
        <p>======================================</p>
    </xsl:template>
    <xsl:template match="Names">
        <table border="1">
            <tr>
                <xsl:apply-templates select="Name/First"/>
            </tr>
            <tr>
                <xsl:apply-templates select="Name/Last"/>
            </tr>
        </table>
    </xsl:template>
    <xsl:template match="First | Last">
        <td><xsl:value-of select="."/></td>
    </xsl:template>
</xsl:stylesheet>

Open in new window

0
 
Geert BormansCommented:
I know about you not wanting a table,
but this way I can show you how to deal with the two lines beneath eachother
I will now directly do the stuff in XSL-FO, to show you the non-table approach

By the way, your source XML is not wellformed (A wellformed XML can only have one root element).
You need to wrap all of that in a container element.
I made it Root, but the XSLT makes the name of that container a wildcard

Here is the source XML I used
<?xml version="1.0" standalone="yes"?>
<Root>
    <Header>My Title</Header>
    <Names>
        <Name>
            <First>Jim</First>
            <Last>Smith</Last>
        </Name>
        <Name>
            <First>Jim2</First>
            <Last>Smith2</Last>
        </Name>
        <Name>
            <First>Jim3</First>
            <Last>Smith3</Last>
        </Name>
    </Names>
    <Footer>My Footer</Footer>  
</Root>

Open in new window

0
 
Geert BormansCommented:
Here is a working (tested with FOP1.0) XSL-FO example
Note that again I used a table.
Table in FO with FOP are clumsy, BUT horizontally alligning blocks with absolute positioning is even clumsier)
Note that I needed some calculation because FOP does not support auto layouts for tables
<?xml version="1.0" encoding="UTF-8"?>
<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="/">
        <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema">
            <fo:layout-master-set>
                <fo:simple-page-master master-name="master" page-height="845.0pt" page-width="598.0pt" margin-top="0.0pt" margin-left="0.0pt" margin-bottom="0.0pt" margin-right="0.0pt">
                    <fo:region-body margin-left="45.0pt" margin-top="44.3pt" margin-bottom="40.0pt" margin-right="34.7pt"/>
                    <fo:region-before extent="44.3pt" precedence="true"/>
                    <fo:region-after extent="40.0pt" precedence="true"/>
                    <fo:region-start extent="45.0pt" precedence="false"/>
                    <fo:region-end extent="34.7pt" precedence="false"/>
                </fo:simple-page-master>
            </fo:layout-master-set>
            <fo:page-sequence master-reference="master" force-page-count="no-force">
                <fo:flow flow-name="xsl-region-body">
                    <fo:block-container >
                        <xsl:apply-templates select="*/*"/>
                    </fo:block-container>
                </fo:flow>
            </fo:page-sequence>
        </fo:root>
    </xsl:template>
    <xsl:template match="Header">
        <fo:block>
            <xsl:text>======================================</xsl:text>
        </fo:block>
        <fo:block>
            <xsl:value-of select="."/>
        </fo:block>
    </xsl:template>
    <xsl:template match="Footer">
        <fo:block>
            <xsl:value-of select="."/>
        </fo:block>
        <fo:block>
            <xsl:text>======================================</xsl:text>
        </fo:block>
    </xsl:template>
    <xsl:template match="Names">
        <fo:block>
            <fo:table width="400pt">
                <fo:table-body>
                    <fo:table-row>
                        <xsl:apply-templates select="Name"/>
                    </fo:table-row>
                </fo:table-body>
            </fo:table>
        </fo:block>
    </xsl:template>
    <xsl:template match="Name">
        <fo:table-cell width="{floor(400 div count(../Name))}pt">
            <xsl:apply-templates select="*"></xsl:apply-templates>
        </fo:table-cell>
    </xsl:template>
    <xsl:template match="Name/*">
        <fo:block>
            <xsl:value-of select="."/>
        </fo:block>
    </xsl:template>
</xsl:stylesheet>

Open in new window

0

Featured Post

Technology Partners: 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!

  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now