This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: My Difficult counting problem


Tim,

This problem looks harder than it is. There are basically two things you need to solve it: (a) to restate the problem in a way more amenable to XSLT, and (b) apply a little fancy XPath (which you can learn by asking on this list :-).

You say "I don't know how loop through the nodes, and keep track of how many
occurrences there are up to the given position", which is basically about half right in the way of a solution. I say half since the XSL Way isn't to "loop through" anything, much less to keep track of anything while doing so. Yet the problem is easily solved if you just say "I want my output in the same order as my input [that's easy], and for each foo, I want my output to get a number reflecting how many foos of the same name came before it".

In XSLT this logic would be:

<xsl:template match="foo">
<xsl:value-of select="count(preceding-sibling::foo[@name=current()/@name]) + 1"/>
</xsl:template>

Spiffed it up to get more exactly what you want:

<xsl:template match="myElement">
<xsl:text>numberOccurrences[] = {</xsl:text>
<xsl:apply-templates/>
<xsl:text>};</xsl:text>
</xsl:template>

<xsl:template match="foo">
<xsl:variable name="thisname" select="@name"/>
<!-- this time we're using a variable just to make the logic a little clearer -->
<xsl:if test="preceding-sibling::foo">
<!-- we want a comma unless we're the first foo -->
<xsl:text>, </xsl:text>
</xsl:if>
<xsl:value-of select="count(preceding-sibling::foo[@name=$thisname]) + 1"/>
<!-- note we used the variable this time instead of current()/@name -->
</xsl:template>

You could do the same thing in a single xsl:template if you used an xsl:for-each inside it for the "loop" (which isn't a loop) -- but it would do the same thing.

Cheers,
Wendell


At 05:48 PM 8/22/2002, you wrote:
hello,

I need some help doing the following, I can't seem to figure out how to do
this in XSL

I need to convert something like this
<myElement>
   <foo name="foobar1"/>
   <foo name="foobar2"/>
   <foo name="foobar1"/>
   <foo name="foobar3"/>
   <foo name="foobar1"/>
   <foo name="foobar1"/>
   <foo name="foobar3"/>
</myElement>

and the output after running it through the XSL would be

numberOccurrences[] = {1, 1, 2, 1, 3, 4, 2};

basically for each foo with a duplicate name you put the occurrence number
of it in the array at the correct position.

You see that foobar1 occurs 4 times,
the 1st occurrence is at position 0, while 2nd occurrence is at position 2,
3rd at position 4, and 5th at position 5. etc.

I don't know how loop through the nodes, and keep track of how many
occurrences there are up to the given position.

======================================================================
Wendell Piez                            mailto:wapiez@mulberrytech.com
Mulberry Technologies, Inc.                http://www.mulberrytech.com
17 West Jefferson Street                    Direct Phone: 301/315-9635
Suite 207                                          Phone: 301/315-9631
Rockville, MD  20850                                 Fax: 301/315-8285
----------------------------------------------------------------------
  Mulberry Technologies: A Consultancy Specializing in SGML and XML
======================================================================


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]