[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

RE: [xsl] Re: Flat -> Hierarchy --- Continue


Subject: RE: [xsl] Re: Flat -> Hierarchy --- Continue
From: "Lars Huttar" <lars_huttar@xxxxxxx>
Date: Thu, 29 May 2003 14:12:09 -0500

Dongling Ding wrote:
> Hi Lars,
> 
> I tried to use the recursive way to generate hierarchy
> structure. The example I have is to generate hierarchy
> by recursively call template itself without looking at
> if it's sibling or child. So the structure would be:
> 
> <A>
>    <B>
>       <C/>
>     </B>
> </A>
> 
> However, my case is when I get a node I have to look
> at another table(the list of nodes containing parent
> and child elements) to see if this node is sibling or
> child.
> 
> 
> <xsl:template match="/doc">
> 
>  <xsl:call-template name="level">
>   <xsl:with-param name="node" select="/doc/Node[1]"/>
>  </xsl:call-template>
> 
> </xsl:template>
> 
> 
> <xsl:template name="level">
>         <xsl:param name="node"/>
> 
>  <xsl:variable name="n"
> select="normalize-space($node)"/>
>  <xsl:element name="{$n}">
> 
>   <xsl:if test="$node/following::Node">
>  ***** Here I have to look at another set of
>  **** elements   
> ****   to decide if the current node is seiling or ***
>   child. If it is seiling, not call the template.
> 
>    <xsl:call-template name="level">
>    <xsl:with-param name="node"
> select="$node/following::Node"/>
>    </xsl:call-template>
> 
>   </xsl:if>
> 
>  </xsl:element>
> 
> </xsl:template>
> 
> 
> So, how can I look at another set of elments. Or just
> like call a function with two parameters and return
> value is boolean in XSLT?

Sure, you could do that... in XSLT 1.0, you'd have to
call a template, and the value wouldn't be boolean as
such, but it could be a string that evaluates to true()
or false() in a boolean context (depending on whether its length
is positive or zero).

But it would probably be simpler to use an inline XPath test,
as follows, than to call the above template with parameters.

Anyway, here would be my solution, assuming your input XML
document is something like
<doc>
  <Members>
    <Member>...</Member>
    ...
  </Members>
  <hierarchy>
    ...
  </hierarchy>
</doc>
  

<xsl:template match="/doc">
  <xsl:apply-templates select="/doc/Members/Member[1]"/>
</xsl:template>

<xsl:template match="Member">

  <xsl:variable name="next" select="following-sibling::Member[1]" />
  <xsl:variable name="next-is-child" select=
     "//hierarchy/node[parent = Label and child = $next/Label]" />

  <xsl:variable name="n" select="normalize-space(Label)"/>

  <xsl:element name="{$n}">
    <!-- If next Member is child of current Member, process it inside
      this result element. -->
    <xsl:if test="$next-is-child">
      <xsl:apply-templates select="$next" />
    </xsl:if>
  </xsl:element>

  <!-- If next Member is not child of current Member, process it outside
     the above result element. -->
  <xsl:if test="not($next-is-child)">
    <xsl:apply-templates select="$next" />
  </xsl:if>
</xsl:template>

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list



Current Thread
Keywords