Re: [xsl] How to find the deepest node?

Subject: Re: [xsl] How to find the deepest node?
From: Dimitre Novatchev <dnovatchev@xxxxxxxxx>
Date: Fri, 8 Apr 2005 06:29:48 +1000
On Apr 8, 2005 1:58 AM, Bert <arm@xxxxxxxxx> wrote:
> Hi,
> 
> I have the following XML-file (see below) and I need to find the deepest
> node of 'title'.
> The resultfile should only contain the titles 'Text 02' and 'Text 03',
> because they are in this case the deepest nodes. The next XML-file I receive
> may contain more nested levels of items and whatever the level of nesting I
> only need to find the deepest titles.
> I know I have to do something with recurse, but I don't know how to start.
> Who can help me on this one?
> 
> Kind regards,
> Bert
> 
> <?xml version="1.0" encoding="UTF-8"?>
> <document>
>  <item>
>    <item>
>      <title>Text 01</title>
>    </item>
>    <item>
>      <item>
>        <title>Text 02</title>
>      </item>
>    </item>
>  </item>
>  <item>
>    <item>
>      <item>
>        <title>Text 03</title>
>      </item>
>    </item>
>  </item>
>  <item>
>    <item>
>      <title>Text 04</title>
>    </item>
>  </item>
> </document>
> 
> Resultfile should contain:
> 
> <?xml version="1.0" encoding="UTF-8"?>
> <document>
>  <item>
>    <item>
>      <item>
>        <title>Text 02</title>
>      </item>
>    </item>
>  </item>
>  <item>
>    <item>
>      <item>
>        <title>Text 03</title>
>      </item>
>    </item>
>  </item>
> </document>


Using FXSL, one will write something as the following:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
 xmlns:f="http://fxsl.sf.net/";
 exclude-result-prefixes="f"
 >
 <xsl:import href="C:/CVS-DDN/fxsl-xslt2/f/func-maxDepth.xsl"/>

 <xsl:output omit-xml-declaration="yes"/>

 <xsl:template match="/">
   <xsl:sequence select=
   "//node()[count(ancestor::node()) = f:maxDepth(/)]/.."/>
 </xsl:template>
</xsl:stylesheet>

and applying this transformation on the originally specified xml
source document produces the wanted result:

                 <title>Text 02</title><title>Text 03</title>


Here's the code of func-maxDepth.xsl:


<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/";
xmlns:MyMaxDepth="MyMaxDepth"
exclude-result-prefixes="xs f MyMaxDepth"
>
   <xsl:import href="func-map.xsl"/>
   
    <xsl:variable name="vfunMaxDepth" 
                  select="document('')/*/MyMaxDepth:*[1]"/>
     
     <xsl:function name="f:maxDepth" as="xs:integer">
       <xsl:param name="pNode" as="node()"/>
       
       <xsl:value-of select=
       "if (not($pNode/node())) then 0
         else 
          max(f:map($vfunMaxDepth, $pNode/node())) + 1"/>
     </xsl:function>
     
     <MyMaxDepth:MyMaxDepth/>
     <xsl:template match="MyMaxDepth:*" mode="f:FXSL">
       <xsl:param name="arg1" as="node()"/>
       
       <xsl:sequence select="f:maxDepth($arg1)"/>
     </xsl:template>
</xsl:stylesheet>


Cheers,
Dimitre Novatchev

Current Thread