xsl-list
[Top] [All Lists]

RE: Re: Flat -> Hierarchy --- Continue

2003-05-29 12:12:09
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