Re: [xsl] Maximum "child-depth" of current node?

Subject: Re: [xsl] Maximum "child-depth" of current node?
From: "Dimitre Novatchev" <dnovatchev@xxxxxxxxx>
Date: Tue, 16 Oct 2007 10:23:07 -0700
> 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.


The provided link to Dave Pawson's FAQ contains XSLT 1.0 solutions.

Also, certainly, one could use FXSL 1.x instead of FXSL 2.0.

> 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.

Thank you Scott. Feel free to email me.


-- 
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.Trenda@xxxxxxxx> wrote:
> 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@xxxxxxxxx]
> Sent: Tuesday, October 16, 2007 12:03 PM
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> 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.Trenda@xxxxxxxx> 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 &lt; $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