Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Arranging data into table rows and columns in XSL? 2

Status
Not open for further replies.

spiel2001

Programmer
Nov 1, 2001
39
US
This is a re-post of my question. The original question was posted here... thread426-188079 there has been no response and I'm still stuck. Would very much appreciate it if someone could lend me a hand on this.

Given a stream of Y data elements, how can I arrange that data into an HTML table of X columns? The problem I am having is figuring out how to properly insert the <TR> and </TR> tags into the output given that the number of elements in the XML data source and the column width of the table are both variable.

Can anyone lend me a hand on this?

The following will construct the cells into a continuous series of columns, but does nothing to break them up into rows. That's the part I can't figure out.

<Data>
<NumColumns value=&quot;8&quot;/>
<ImgURI value=&quot;something&quot;/>
<ImgURI value=&quot;something-else&quot;/>
<ImgURI value=&quot;another-one&quot;/>
<ImgURI value=&quot;...&quot;/>
</Data>

<xsl:template match=&quot;/&quot;>
<table>
<xsl:for-each select=&quot;/Data/ImgURI&quot;>
<xsl:call-template name=&quot;table-cell&quot;/>
</xsl:for-each>
</table>
</xsl:template>

<xsl:template name=&quot;table-cell&quot;>
<td>
<img><xsl:attribute name=&quot;src&quot;><xsl:value-of
select=&quot;@value&quot;/></xsl:attribute>
</img>
</td>
</xsl:template>

 
just to clarify before i write a load of useless code..... :)

you want a table of all the &quot;/Data/ImgURI/@value&quot;'s but you want the table to wrap after every n images. where n would be some max number you could choose?
 
Mr. Tom --

That is correct. The number of columns in the table is a user selected variable. But, to be honest, even if it was a fixed value, I'm still not sure how to break it into rows within the XSL.

I could, of course, break it into rows in the XML itself by breaking the data up into <TableRow> nodes or something like that. However, that would also mean that I would have to move the name sorting processing into the XML generator as opposed to letting the client take on the responsibility of sorting the data.

So, I'm tying to figure out how to break the output up (wrap it) into multiple rows on the XSL side.

If you could help you would be saving me -- I've spent three days on it and just can't see the woods for the trees anymore.

If there's no solution to the problem, that's fine, too... so long as I know that there's no solution. Won't make me happy, but waddaya do?

~smile~

and TIA
 
<xsl:variable name=&quot;max&quot; value=&quot;5&quot;/>
<xsl:for-each select=&quot;ImgURI[position() mod $max = 1]&quot;>
<tr>
<xsl:apply-templates select=&quot;.|following-sibling::ImgURI[position() < $max]&quot;/>
</tr>
<xsl:for-each>

i picked this up from which is the best collection of xsl snippets there is (bookmark it now). it doesn't look like the most efficient thing but unless you've got more than 500 ImgURI's you won't notice.
if you need any of it explaining just shout.
 
MrTom --

Thanks a million. I'll give a holler if I get stuck on it.

You saved my butt.

I'm getting there, but I think the learning curve may kill me first ~grin~
 
Just as a heads up for the benefit of anyone who may be reading over our shoulder...

This did work in that it broke the tables up into rows of &quot;MaxColumns&quot; each as desired. However, it should be noted that it also broke the sort by image name originally intended.

Here's what happens... if the list of images is longer than a single table row and is unsorted, the XSL code has the net effect of breaking the images up into groups of MaxColumns images each and then sorting the order of each group as opposed to sorting all of the images by name.

As a result, the images appear in &quot;natural&quot; order within each row, however, the rows are sorted in alphabetical order by the name of the first image in each row.

Here's the final &quot;working&quot; code with the &quot;broken&quot; image name sort...

<Data>
<MaxColumns value=&quot;8&quot;/>
<Group>
<Name value=&quot;Group 1&quot;/>
<Image>
<Name value=&quot;Img1&quot;/>
<URI value=&quot;img1.gif&quot;/>
</Image>
<Image>
<Name value=&quot;Img2&quot;/>
<URI value=&quot;img2.gif&quot;/>
</Image>
...
</Group>
...
</Data>

<xsl:stylesheet>

<xsl:variable name=&quot;max_columns&quot;
select=&quot;/Data/MaxColumns/@value&quot;/>

<xsl:template match=&quot;/&quot;>
<xsl:for-each select=&quot;Group&quot;>
<xsl:sort select=&quot;Name/@value&quot;/>
<xsl:call-template name=&quot;group-table&quot;/>
</xsl:for-each>
</xsl:template>

<xsl:template name=&quot;group-table&quot;>
<table width=&quot;100%&quot;>
<tr>
<td bgcolor=&quot;#999999&quot; valign=&quot;middle&quot;>
<xsl:attribute name=&quot;colspan&quot;>
<xsl:value-of select=&quot;$max_columns&quot;/>
</xsl:attribute>
<xsl:value-of select=&quot;Name/@value&quot;/>
</td>
</tr>
<xsl:for-each
select=&quot;Image[position() mod $max_columns = 1]&quot;>
<tr>
<xsl:apply-templates
select=&quot;.|following-sibling::Image[position()
< $max_columns]&quot;>
<xsl:sort select=&quot;Name/@value&quot;/>
</xsl:apply-templates>
</tr>
</xsl:for-each>
</table>
<br/>
</xsl:template>

<xsl:template match=&quot;Image&quot;>
<xsl:param name=&quot;base&quot;/>
<td>
<img>
<xsl:attribute name=&quot;src&quot;>
<xsl:value-of select=&quot;URI/@value&quot;/>
</xsl:attribute>
</img>
<br/>
<xsl:value-of select=&quot;Name/@value&quot;/>
</td>
</xsl:template>

</xsl:stylesheet>
 
oh yeah, i forgot about the sorting. sorting is a bit funny sometimes.

you can create a variable just before drawing the table using

<xsl:variable name=&quot;sorted&quot;>
<xsl:for-each select=&quot;Image&quot;>
<xsl:sort select=&quot;Name/@value&quot;/>
<xsl:copy-of select=&quot;.&quot;/>
</xsl:for-each>
</xsl:variable>

then do a <xsl:for-each select=&quot;$sorted/Image&quot;>

i tried this quickly but got an error with my xsl processor but it may be buggy. i don't see why it shouldn't work with msxml.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top