xsl-list
[Top] [All Lists]

Re: Traversing the tree

2005-09-08 16:24:21
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(_at_)s-s-t(_dot_)com 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(_at_)yahoo(_dot_)com> 
09/08/2005 04:09 PM
Please respond to
xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com


To
xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
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/

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



<Prev in Thread] Current Thread [Next in Thread>