Re: [xsl] Walking a tree

Subject: Re: [xsl] Walking a tree
From: Anton Triest <anton@xxxxxxxx>
Date: Fri, 29 Oct 2004 12:12:58 +0200
Hi Marcus,

Here's a solution that uses apply-templates with a mode (mode="pageNav") instead of call-template. I'm assuming that you can pass the name of the clicked node in a global param:

<xsl:param name="target" select="'node23'"/>

Then, instead of <xsl:call-template name="pageNav"><xsl:with-param.../xsl:call-template>

<xsl:apply-templates select="node" mode="pageNav"/>

and this template:

   <xsl:template match="node | leaf" mode="pageNav">
       <xsl:copy>
           <xsl:copy-of select="@*"/>
           <xsl:apply-templates select="node" mode="pageNav"/>
           <xsl:if test="@name = $target">
               <xsl:apply-templates select="leaf" mode="pageNav"/>
           </xsl:if>
       </xsl:copy>
   </xsl:template>

output:

   <node>
       <node name="node1"/>
       <node name="node2">
           <node name="node22"/>
           <node name="node23">
               <leaf name="leaf231"/>
               <leaf name="leaf232"/>
           </node>
           <node name="node24"/>
       </node>
   </node>

Cheers,
Anton


Marcus Andersson wrote:


I'm trying to walk a tree with the following structure (more or less):

<node>
  <node name="node1">
    <leaf name="leaf1"/>
    <leaf name="leaf2"/>
  </node>
  <node name="node2">
    <node name="node22">
      <leaf name="leaf221"/>
      <leaf name="leaf222"/>
    </node>
    <node name="node23">
      <leaf name="leaf231"/>
      <leaf name="leaf232"/>
    </node>
    <node name="node24">
      <leaf name="leaf241"/>
      <leaf name="leaf242"/>
    </node>
  </node>
</node>

Then I want to render a graphical tree based on this and on a selected node (for example, if I have clicked on node24 I want the tree to be unfolded downto that node including it's children. I don't want node23 and node22 to be unfolded and neither node1).

I have some almost working code to render this except that a test isn't working so when I click on node24 then node22 and node23 get unfolded as well.

  <xsl:template name="pageNav">
    <xsl:param name="targetNode"/>
    <xsl:param name="currentNode"/>
      <xsl:for-each select="$currentNode/node|$currentNode/leaf">
    ... lots of presentation code ...

<!-- I guess it's this test that should be modified -->
<xsl:if test=". = $targetNode/ancestor-or-self::node">
<xsl:call-template name="pageNav">
<xsl:with-param name="targetNode" select="$targetNode"/>
<xsl:with-param name="currentNode" select="."/>
</xsl:call-template>
</xsl:if>
</xsl:for-each>
</xsl:template>


Any suggestions? Do you need more input? I'm using MSXML3 so node-set() is acceptable (although it shouldn't be needed)

/Marcus

Current Thread