Re: [xsl] Traversing the tree

Subject: Re: [xsl] Traversing the tree
From: "Agnisys Technology \(P\) Ltd." <agnisys@xxxxxxxxx>
Date: Thu, 8 Sep 2005 16:24:21 -0700 (PDT)
 > That's a fairly non-trivial proposition, actually.
 Bummer, I thought there would be some (perhaps complex) Xpath expression I could use.  
 Actually the last 0 for A10 isn't a typo. Basically any new <a> node should restart the counter.
 But I'll work with what you provided and see if I can solve that. 
Thanks once again!
Anupam.

--- JBryant@xxxxxxxxx wrote:

> That's a fairly non-trivial proposition, actually.
> 
> Here's one solution. The algorithm is to gather up all the reg nodes into 
> a variable (to remove any other structure) and then walk through the list 
> of nodes in the variable. To do the walking, I wrote a recursive template 
> that figures out what the values for the current reg node should be and, 
> if a subsequent reg node exists, calls itself again.
> 
> Here's the XSL
> 
> <?xml version="1.0" encoding="UTF-8"?>
> 
> <xsl:stylesheet version="1.0" 
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
> 
>   <xsl:output method="html" indent="yes"/>
>  
>   <xsl:variable name="reg">
>     <xsl:for-each select="//reg">
>       <xsl:copy-of select="."/>
>     </xsl:for-each>
>   </xsl:variable>
> 
>   <xsl:template match="top">
>     <html>
>       <body>
>         <table>
>           <tr>
>             <th>reg ID</th><th>Offset Value</th>
>           </tr>
>           <xsl:call-template name="figure-offset">
>             <xsl:with-param name="offset" select="0"/>
>             <xsl:with-param name="position" select="1"/>
>           </xsl:call-template>
>         </table>
>       </body>
>     </html>
>   </xsl:template>
>  
>   <xsl:template name="figure-offset">
>     <xsl:param name="offset"/>
>     <xsl:param name="position"/>
>     <xsl:choose>
>       <xsl:when test="$reg//reg[position() = $position]/@offset">
>         <tr>
>           <td><xsl:value-of select="$reg//reg[position() = 
> $position]"/></td>
>           <td><xsl:value-of select="$reg//reg[position() = 
> $position]/@offset"/></td>
>         </tr>
>         <xsl:if test="$reg//reg[position() = $position]/following::reg">
>           <xsl:call-template name="figure-offset">
>             <xsl:with-param name="offset" select="$reg//reg[position() = 
> $position]/@offset + 1"/>
>             <xsl:with-param name="position" select="$position + 1"/>
>           </xsl:call-template>
>         </xsl:if>
>       </xsl:when>
>       <xsl:otherwise>
>         <tr>
>           <td><xsl:value-of select="$reg//reg[position() = 
> $position]"/></td>
>           <td><xsl:value-of select="$offset"/></td>
>         </tr>
>         <xsl:if test="$reg//reg[position() = $position]/following::reg">
>           <xsl:call-template name="figure-offset">
>             <xsl:with-param name="offset" select="$offset + 1"/>
>             <xsl:with-param name="position" select="$position + 1"/>
>           </xsl:call-template>
>         </xsl:if>
>       </xsl:otherwise>
>     </xsl:choose>
>   </xsl:template>
> 
> </xsl:stylesheet>
> 
> And here's the output (from Saxon):
> 
> <html>
>    <body>
>       <table>
>          <tr>
>             <th>reg ID</th>
>             <th>Offset Value</th>
>          </tr>
>          <tr>
>             <td>A1</td>
>             <td>0</td>
>          </tr>
>          <tr>
>             <td>A2</td>
>             <td>1</td>
>          </tr>
>          <tr>
>             <td>A3</td>
>             <td>10</td>
>          </tr>
>          <tr>
>             <td>A4</td>
>             <td>11</td>
>          </tr>
>          <tr>
>             <td>A5</td>
>             <td>12</td>
>          </tr>
>          <tr>
>             <td>A6</td>
>             <td>24</td>
>          </tr>
>          <tr>
>             <td>A7</td>
>             <td>25</td>
>          </tr>
>          <tr>
>             <td>A8</td>
>             <td>6</td>
>          </tr>
>          <tr>
>             <td>A9</td>
>             <td>7</td>
>          </tr>
>          <tr>
>             <td>A10</td>
>             <td>8</td>
>          </tr>
>       </table>
>    </body>
> </html>
> 
> You specified a value of 0 for the last offset, but I am assuming that's a 
> typo.
> 
> As usual, I'm sure there are other ways.
> 
> Jay Bryant
> Bryant Communication Services
> (presently consulting at Synergistic Solution Technologies)
> 
> 
> 
> 
> 
> "Agnisys Technology \(P\) Ltd." <agnisys@xxxxxxxxx> 
> 09/08/2005 04:09 PM
> Please respond to
> xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> 
> 
> To
> xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> cc
> 
> Subject
> [xsl] Traversing the tree
> 
> 
> 
> 
> 
> 
> Hi,
>   This is probably simple for the experts of the group but I can't figure 
> this out. Problem I got
> stuck on was how to find the closest preceding-sibling node with an offset 
> attribute, then count
> the nodes that don't have the attribute since that node.
>  
> Input :
> <top>
>      <a>
>           <reg                > A1 </reg>
>           <reg                > A2 </reg>
>           <reg  offset="10"   > A3 </reg>
>           <reg                > A4 </reg>
>           <reg                > A5 </reg>
>           <reg  offset="24"   > A6 </reg>
>           <reg                > A7 </reg>
>       </a>
>       <a>
>           <reg  offset="6"> A8 </reg>
>           <reg            > A9 </reg>
>       </a>
>       <a>
>           <reg            > A10 </reg>
>       </a>
>  </top>
> 
> Output:
> A1 : 0
> A2 : 1
> A3 : 10
> A4 : 11
> A5 : 12
> A6 : 24
> A7 : 25
> A8 : 6
> A9 : 7
> A10: 0
> 
> So, start with 0 and count unless @offset is encountered, if so, jump to 
> the offset and start
> 
=== message truncated ===



	
		
______________________________________________________
Click here to donate to the Hurricane Katrina relief effort.
http://store.yahoo.com/redcross-donate3/

Current Thread