This is a question that I realize has been asked a million different ways already with just as many different solutions, but try as I might, I just can't find a solution that will give me the desired effect I want. I am creating xsl fo templates to give to Apache FOP to render a PDF. The PDF I am rendering is fairly straight forward, it simply has a table with repeating rows in it, and I want to control the order that the rows render in based on sorting a child tag of the repeating node I selected based on it's integer value.
My XML looks like this...
<?xml version="1.0" encoding="UTF-8"?>
<Stops>
<Stop>
<Sequence>1</Sequence>
<Address>
<Street>123 main st</Street>
<City>Toronto</City>
<Postal_Code>L1G4F4</Postal_Code>
</Address>
</Stop>
<Stop>
<Sequence>3</Sequence>
<Address>
<Street>1441 First st</Street>
<City>Toronto</City>
<Postal_Code>L1G4F4</Postal_Code>
</Address>
</Stop>
<Stop>
<Sequence>2</Sequence>
<Address>
<Street>467 Center st</Street>
<City>Vancouver</City>
<Postal_Code>L9V4A1</Postal_Code>
</Address>
</Stop>
</Stops>
My xslfo code looks like...
<fo:table>
<fo:table-column column-width="proportional-column-width(50)" column-number="1"/>
<fo:table-column column-width="proportional-column-width(50)" column-number="2"/>
<fo:table-body>
<xsl:call-template name="sort-stops"/>
</fo:table-body>
</fo:table>
With...
<xslt:template select="Stops" name="sort-stops">
<xsl:sort slect="stop/sequence"/>
<xsl:for-each select="stop">
<fo:table-row>
<fo:table-cell>
<fo:block>
<xsl:value-of select="sequence"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:for-each>
</xslt:template>
There is obviously something wrong with my approach to this, but I have no idea where to go from here anymore. If I stick in simple code to insert a block in my sort-stops template definition, that will show up, but it really seems like the problem is in how I access the child nodes of my stop element. Can anyone please give me some direction as to how I can have the table rows sort the stops based on the sequence tag and genreate repeating rows in this order?
You didn't post your required output, but I am guessing you want to do something like this:
XSLT 1.0
<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 method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<fo:table>
<fo:table-column column-width="proportional-column-width(50)" column-number="1"/>
<fo:table-column column-width="proportional-column-width(50)" column-number="2"/>
<fo:table-body>
<xsl:apply-templates select="Stops/Stop">
<xsl:sort select="Sequence" data-type="number" order="ascending"/>
</xsl:apply-templates>
</fo:table-body>
</fo:table>
</xsl:template>
<xsl:template match="Stop">
<fo:table-row>
<fo:table-cell>
<fo:block>
<xsl:value-of select="Sequence"/>
</fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:template>
</xsl:stylesheet>
which given your example input will produce:
<?xml version="1.0" encoding="UTF-8"?>
<fo:table xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:table-column column-width="proportional-column-width(50)" column-number="1"/>
<fo:table-column column-width="proportional-column-width(50)" column-number="2"/>
<fo:table-body>
<fo:table-row>
<fo:table-cell>
<fo:block>1</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell>
<fo:block>2</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell>
<fo:block>3</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
Note that XML is case-sensitive; select="sequence"
does not select <Sequence>
.