xsl-list
[Top] [All Lists]

Re: [xsl] using position() inside Muenchian groups?

2008-10-13 22:18:34
At 2008-10-14 12:15 +1100, Eric Scheid wrote:
I've got data that looks like this:
...
I want to produce output that looks like this:
...
I'm thinking I could use Muenchian grouping to pull out all the PRDC
sub-fields for a record (and then all the DRCT, WRTR, etc), and I also know
how to use position() to access the corresponding sibling...

Actually, that isn't quite precise. That isn't what position() returns. The function returns the current position within the set of nodes in the scope of the instruction that used select=.

For example if you have:

 <test>
   <x/>
   <x/>
   <x/>
 </test>

.... and you have:

  <xsl:template match="x">
     <xsl:if test="position()>1">,</xsl:if>
     <xsl:value-of select="position()"/>
  </xsl:template>

.... and you first write your test template as follows:

  <xsl:template match="test">
    <xsl:apply-templates select="*"/>
  </xsl:template>

.... you will get:   1,2,3

However, if you have in your test template the following:

  <xsl:template match="test">
    <xsl:apply-templates/>
  </xsl:template>

.... you will get:   ,2,4,6

Because in the first <xsl:apply-templates/> you are selecting all child elements, but in the second <xsl:apply-templates/> you are selecting all child nodes. There are text nodes in between the <x/> elements (unless you are running Microsoft XSLT in which case there are no such text nodes).

So position() isn't used to access the corresponding sibling, it is used to access the corresponding member of the current node list in the context of the last select= for <xsl:apply-templates/> or <xsl:for-each/>.

So you get different answers for the same set of sibling <x> elements based on how you are selecting nodes for processing ... it really doesn't have a direct relationship to siblings, only indirect if the siblings are the only things selected.

 <xsl:variable name="p" select="position()"/>
 <xsl:if test="$p>1"><xsl:text>, </xsl:text></xsl:if>
 <xsl:value-of select="ancestor::fmp:ROW/fmp:COL[$crew_name]/fmp:DATA[$p]"/>

... but I suspect these won't play together nicely because (eg) the
position() of the second producer (PRDC) in the first title would be "2",
and not "6", and thus ancestor::fmp:ROW/fmp:COL[$crew_name]/fmp:DATA[$p]
would grab the 2nd $crew_name of *all* the siblings, not the 2nd producer's
$crew_name.

Am I right? If so, how would I go about doing this?

A lot depends on the select= before your code is invoked.

It doesn't hurt to do some experimentation to see the kinds of results you get.

With the Muenchian method you are doing a select= to get the first record in document order for each unique value ... so, then, in that <xsl:for-each> the position() function will return the number order. If you sort the records, then position() returns the sorted order.

So I think your question cannot be answered without seeing more details of your code.

I hope this helps!

. . . . . . . . . . . . . . Ken

(ps, yes, I am really starting to hate Filemaker's XML export format)

I can imagine!


--
Upcoming XSLT/XSL-FO hands-on courses:      Wellington, NZ 2009-01
Training tools: Comprehensive interactive XSLT/XPath 1.0/2.0 video
Video sample lesson:    http://www.youtube.com/watch?v=PrNjJCh7Ppg
Video course overview:  http://www.youtube.com/watch?v=VTiodiij6gE
G. Ken Holman                 mailto:gkholman(_at_)CraneSoftwrights(_dot_)com
Crane Softwrights Ltd.          http://www.CraneSoftwrights.com/s/
Male Cancer Awareness Nov'07  http://www.CraneSoftwrights.com/s/bc
Legal business disclaimers:  http://www.CraneSoftwrights.com/legal


--~------------------------------------------------------------------
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>
--~--