Re: [xsl] Count of previous nodes until a child node of a previous node is found with certain attribute value

Subject: Re: [xsl] Count of previous nodes until a child node of a previous node is found with certain attribute value
From: "Mukul Gandhi" <gandhi.mukul@xxxxxxxxx>
Date: Sun, 27 May 2007 20:20:28 +0530
Below is another XSLT 1.0 solution:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
version="1.0">

<xsl:output method="text" />

 <xsl:template match="body">
   <xsl:text>p node value Count&#xa;</xsl:text>
   <xsl:apply-templates select="p[not(component)]" />
 </xsl:template>

 <xsl:template match="p">
   <xsl:variable name="text" select="normalize-space()" />
   <xsl:variable name="x">
     <xsl:call-template name="findCount">
       <xsl:with-param name="prev-p" select="preceding-sibling::p[1]" />
       <xsl:with-param name="result" select="0" />
     </xsl:call-template>
   </xsl:variable>
   <xsl:value-of select="$text" /><xsl:text> </xsl:text><xsl:value-of
select="$x" /><xsl:text>&#xa;</xsl:text>
 </xsl:template>

 <xsl:template name="findCount">
   <xsl:param name="prev-p" />
   <xsl:param name="result" />

   <xsl:choose>
     <xsl:when test="$prev-p/self::p and not($prev-p/component)">
       <xsl:call-template name="findCount">
         <xsl:with-param name="prev-p"
select="$prev-p/preceding-sibling::p[1]" />
         <xsl:with-param name="result" select="$result + 1" />
       </xsl:call-template>
     </xsl:when>
     <xsl:otherwise>
       <xsl:value-of select="$result" />
     </xsl:otherwise>
   </xsl:choose>
 </xsl:template>

</xsl:stylesheet>

This when applied to the given XML, produces the desired output:

p node value    Count
text                 0
text2               1
text3               0
text4               1
text5               2
text6               3
text7               0
text8               1
text9               2

PS: I have used a recursive named template, to walk through "p"
elements along preceding-sibling axis.

On 5/27/07, Jeremy Freedman <jeremy.freedman@xxxxxxxxx> wrote:
Hi all,

I'm the first to admit I'm not XSL expert, but I've been stuck on this
one for hours and I'm hoping someone can help me out.

I've found similar posts where a user is looking for a count of
following nodes until an attribute is found, but not close enough to
what I'm looking to do.

Assuming we have this XML structure:

<body>
   <p>
         text
   </p>
  <p>
         text2
   </p>
   <p>
         <component name="newpage" />
   </p>
   <p>
         text3
   </p>
  <p>
         text4
   </p>
   <p>
         text5
   </p>
  <p>
         text6
   </p>
   <p>
         <component name="newpage" />
   </p>
   <p>
         text7
   </p>
  <p>
         text8
   </p>
   <p>
         text9
   </p>
</body>


I want to be able to find the count of preceding "p" nodes from the p node I am on, up until I find a "p" node with a child node named "component" with attribute name=newpage.

Examples:

If I am on the p node whose value is "text8", I should get a count of
1 because there is only 1 previous p node before I find a p node with
the component node with attribute name=newpage.

p node value            Count
text                          0
text2                        1
text3                        0
text4                        1
text5                        2
text6                        3
text7                        0
text8                        1
text9                        2


You will be my personal hero is you can help me out!


Much thanks,

Jeremy


--
Regards,
Mukul Gandhi

Current Thread