Dmitre,
Thanks for your reply. I'm a big fan of your FXSL methods - I'd actually
like to speak with you sometime about some extension ideas I had a while
ago. Please e-mail me at your convenience if you'd be interested in
hearing them.
As far as the issue at hand, this might've gotten lost:
... and I know we've had this discussion before - I'm stuck with XSLT
1.0.
~ Scott
-----Original Message-----
From: Dimitre Novatchev [mailto:dnovatchev(_at_)gmail(_dot_)com]
Sent: Tuesday, October 16, 2007 12:03 PM
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: Re: [xsl] Maximum "child-depth" of current node?
Do have a look here:
http://www.dpawson.co.uk/xsl/sect2/N2193.html
The most up-to-date XSLT 2.0 code is:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:f="http://fxsl.sf.net/"
exclude-result-prefixes="xs f"
<xsl:import href="../f/func-map.xsl"/>
<xsl:function name="f:maxDepth" as="xs:integer">
<xsl:param name="pNode" as="node()"/>
<xsl:sequence select=
"if(not($pNode/node())) then 0
else
max(f:map(f:maxDepth(), $pNode/node() ) ) + 1
"
/>
</xsl:function>
<xsl:function name="f:maxDepth" as="element()">
<f:maxDepth/>
</xsl:function>
<xsl:template match="f:maxDepth" mode="f:FXSL" as="xs:integer">
<xsl:param name="arg1" as="node()"/>
<xsl:sequence select="f:maxDepth($arg1)"/>
</xsl:template>
</xsl:stylesheet>
and the logic is concentrated just in these three lines:
if(not($pNode/node())) then 0
else
max(f:map(f:maxDepth(), $pNode/node() ) ) + 1
--
Cheers,
Dimitre Novatchev
---------------------------------------
Truly great madness cannot be achieved without significant intelligence.
---------------------------------------
To invent, you need a good imagination and a pile of junk
-------------------------------------
You've achieved success in your field when you don't know whether what
you're doing is work or play
On 10/16/07, Scott Trenda <Scott(_dot_)Trenda(_at_)oati(_dot_)net> wrote:
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>
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail:
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail:
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail:
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--