Subject: [xsl] Maximum "child-depth" of current node? From: "Scott Trenda" <Scott.Trenda@xxxxxxxx> Date: Tue, 16 Oct 2007 10:31:02 -0500 |
Hey XSL-List. Got a bugger of a problem that started to drive me nuts yesterday, figured I'd ask here first thing today to avoid pulling my hair out over this. :P I just found out yesterday that the nest-hierarchy system I set up for a recent big project has to essentially be done in _reverse_ for a different format, but this one isn't as simple. I'm basically making a list header hierarchy into a nested HTML table header in one format, and I have to make it into similar-looking CSV in the other format. Take this example data: <x> <c>col1</c> <c>col2</c> <g n='grp1'> <c>col3</c> <c>col4</c> <c>col5</c> </g> <g n='grp2'> <c>col6</c> <g n='grp3'> <c>col7</c> <c>col8</c> </g> <c>col9</c> </g> <c>col10</c> <c>col11</c> </x> HTML output: ------------------------------------------------------------------------ -------- | | | grp1 | grp2 | | | | | |--------------------|---------------------------| | | | | | | | | | grp3 | | | | | | | | | | |-------------| | | | | col1 | col2 | col3 | col4 | col5 | col6 | col7 | col8 | col9 | col10 | col11 | ------------------------------------------------------------------------ -------- CSV output: , , , , ,grp2, , , , , , ,grp1, , , ,grp3, , , , col1,col2,col3,col4,col5,col6,col7,col8,col9,col10,col11 For HTML (this part is done already), I have a key that gets the <c> or <g> elements at a specified depth - since col1, col2, col10, and col11 actually exist in the first <tr> of the table, they belong with grp1 and grp2 at the top level. But those cells are bottom-valigned because there's a data table beneath it, and it makes sense to have the label sitting directly above it. In the CSV output, I need to alter the structure so they actually appear there in the result document. With that, here's the key I'm using for the HTML version: <key name="cols-at-depth" match="c|g[.//c]" use="count(ancestor::g) + 1"/> Later in the stylesheet, I find the max column depth ($total-header-levels), start processing with key('cols-at-depth', 1) and loop until I'm at key('cols-at-depth', $total-header-levels). But for the CSV version, I essentially need to go the opposite way - rather than counting the node's depth from its farthest <g> ancestor, I need to count the depth of its deepest child branch. If I could do this with a key, it would definitely be best, but just finding the algorithm to get it in the first place would be a good start. My strategy from there is to do a loop similar to the HTML cols-at-depth algorithm above, but the CSV version would hold off on making the parent group entries until absolutely necessary (at the point where the output is on the nth-to-last output row, and parent group has at least one branch n levels deep). Any ideas on XPath trickery I could use here? I've included a trimmed-down version of the HTML-output stylesheet at the bottom. ... and I know we've had this discussion before - I'm stuck with XSLT 1.0. Thanks in advance! ~ Scott <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" encoding="utf-8"/> <xsl:key name="columns-at-depth" match="c|g[.//c]" use="count(ancestor::g) + 1"/> <xsl:variable name="total-header-levels"> <xsl:for-each select="//c"> <xsl:sort select="count(ancestor::g)" data-type="number"/> <xsl:if test="position() = last()"> <xsl:value-of select="count(ancestor::g) + 1"/> </xsl:if> </xsl:for-each> </xsl:variable> <xsl:template match="/"> <table> <xsl:call-template name="loop-rows"/> </table> </xsl:template> <xsl:template name="loop-rows"> <xsl:param name="row" select="1"/> <tr> <xsl:apply-templates select="key('columns-at-depth', $row)"/> </tr> <xsl:if test="$row < $total-header-levels"> <xsl:call-templates name="loop-rows"> <xsl:with-param name="row" select="$row + 1"/> </xsl:apply-templates> </xsl:if> </xsl:template> <xsl:template match="c"> <th rowspan="{$total-header-levels - count(ancestor::g)}"> <xsl:value-of select="."/> </th> </xsl:template> <xsl:template match="g"> <th colspan="{count(.//c)}"> <xsl:value-of select="@n"/> </th> </xsl:template> </xsl:stylesheet>
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] ANN: RenderX announces first , Lyudmyla Novosilska | Thread | Re: [xsl] Maximum "child-depth" of , Dimitre Novatchev |
Re: [xsl] Sorting Two Dimensional T, David Carlisle | Date | Re: [xsl] Sorting Two Dimensional T, David Carlisle |
Month |