[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: using position() inside Muenchian groups?

Subject: Re: using position() inside Muenchian groups?
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Tue, 14 Oct 2008 08:42:19 -0400
Re:  using position() inside Muenchian groups?
At 2008-10-14 14:07 +1100, Eric Scheid wrote:
I'm only at the stage of cargo culting at the moment :-( I estimate it would
take about 2 hours of fumbling in the dark to figure out just the Muenchian
grouping code, which could all be for naught if it turns out that position()
within the for-each for the keyed group is relative to the subset and not
the original set.

Now with this email I'm not so sure you need the Muenchian method at all ... because your output is ordered irrespective of your input order. Your details have I hope clarified for me what I now think you were looking for.


At 2008-10-14 12:15 +1100, Eric Scheid wrote:
I want to produce output that looks like this:

> Title: The Alice
> Producer: Alan Jones*, Zachary Azimuth
> Director: Bill Smith
> Writer: Dicky Dickens
>
> Title: Mini Mini
> Producer: Wal Walliams*
> Director: Wal Walliams*
> Writer: Wal Walliams*

I see above it is always "producer" then "director" then "writer", yet in your input data the second production of your input has the data ordered "director" then "producer" then "writer". Which means with any kind of grouping you would not get the correct order for the second production, not even if you sorted it.


I also see that you've asterisked the wrong name in the first production.

I now see how you are trying to group within respective sets of siblings that are not grouped hierarchically. Again a clue that traditional grouping techniques we've been discussing are not applied in traditional approaches.

There is an instruction that by definition works on axes and not on the current node list: <xsl:number/> ... but it is designed for exposing tree positions in formatted results, I very rarely find a need to use it in a "programming style" within my code logic. I do find my students quickly resort to using <xsl:number/> when position() is better, but in your case position() is *not* better.

Below in eric1.xsl is code to give you what I think you want, but only because the ordering seems by the evidence to be set by you and not by the data. If you need to do it by the order of the data then the code in eric2.xsl will do the uniqueness based on what is there, not what you are looking for.

I'm working on it :-) Hard to write code like this though because I don't
know if the wrong answers I'm getting is because I got a bug in my code, or
because it is simply impossible.

Since XSLT is Turing Complete I would be hard pressed to think that any required solution is "impossible" ... it may be inelegant, it may be inefficient, it may even take a couple of passes, but it probably isn't impossible.


I hope one of these solutions below helps.

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


T:\ftemp>type eric.xml <FMPXMLRESULT xmlns="http://www.filemaker.com/fmpxmlresult"> <RESULTSET FOUND="3"> <ROW MODID="0" RECORDID="1"> <COL><DATA>1</DATA></COL> <COL><DATA>The Alice</DATA></COL> <COL> <DATA>PRDC</DATA> <DATA>EXCP</DATA> <DATA>DRCT</DATA> <DATA>DOPH</DATA> <DATA>EXCP</DATA> <DATA>PRDC</DATA> <DATA>WRTR</DATA> </COL> <COL> <DATA>Alan Jones</DATA> <DATA>Big Cheese</DATA> <DATA>Bill Smith</DATA> <DATA>Camera Guy</DATA> <DATA>Little Cheese</DATA> <DATA>Zachary Azimuth</DATA> <DATA>Dicky Dickens</DATA> </COL> <COL> <DATA></DATA> <DATA></DATA> <DATA>Yes</DATA> <DATA></DATA> <DATA></DATA> <DATA></DATA> <DATA></DATA> </COL> </ROW> <ROW MODID="0" RECORDID="3"> <COL><DATA>3</DATA></COL> <COL><DATA>Mini Mini</DATA></COL> <COL>

            <DATA>DRCT</DATA>
            <DATA>PRDC</DATA>
            <DATA>WRTR</DATA>
        </COL>
        <COL>
            <DATA>Wal Walliams</DATA>
            <DATA>Wal Walliams</DATA>
            <DATA>Wal Walliams</DATA>
        </COL>
        <COL>
            <DATA>Yes</DATA>
            <DATA>Yes</DATA>
            <DATA>Yes</DATA>
        </COL>
    </ROW>
</RESULTSET>
</FMPXMLRESULT>

T:\ftemp>call xslt eric.xml eric1.xsl eric1.txt

T:\ftemp>type eric1.txt
Title: The Alice
Producers: Alan Jones,Zachary Azimuth
Director: Bill Smith*
Writer: Dicky Dickens

Title: Mini Mini
Producer: Wal Walliams*
Director: Wal Walliams*
Writer: Wal Walliams*

T:\ftemp>type eric1.xsl
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:fm="http://www.filemaker.com/fmpxmlresult"
                version="1.0">

<xsl:output method="text"/>

<xsl:variable select="1"  name="title_id" />
<xsl:variable select="2"  name="title" />
<xsl:variable select="3"  name="crew_role" />
<xsl:variable select="4"  name="crew_name" />
<xsl:variable select="5"  name="crew_flag" />

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

<xsl:template match="fm:ROW">
  <xsl:if test="position()>1"><xsl:text>&#xa;</xsl:text></xsl:if>
  <xsl:text>Title: </xsl:text>
  <xsl:value-of select="fm:COL[$title]/fm:DATA"/>
  <xsl:text>&#xa;</xsl:text>
  <xsl:call-template name="do-role">
    <xsl:with-param name="title">Producer</xsl:with-param>
    <xsl:with-param name="indicator">PRDC</xsl:with-param>
  </xsl:call-template>
  <xsl:call-template name="do-role">
    <xsl:with-param name="title">Director</xsl:with-param>
    <xsl:with-param name="indicator">DRCT</xsl:with-param>
  </xsl:call-template>
  <xsl:call-template name="do-role">
    <xsl:with-param name="title">Writer</xsl:with-param>
    <xsl:with-param name="indicator">WRTR</xsl:with-param>
  </xsl:call-template>
</xsl:template>

<xsl:template name="do-role">
<xsl:param name="title"/>
<xsl:param name="indicator"/>
<xsl:variable name="production" select="."/>
<xsl:if test="fm:COL[$crew_role]/fm:DATA[.=$indicator]">
<xsl:value-of select="$title"/>
<xsl:if test="count(fm:COL[$crew_role]/fm:DATA[.=$indicator])>1">s</xsl:if>
<xsl:text>: </xsl:text>
<!--find all-->
<xsl:for-each select="fm:COL[$crew_role]/fm:DATA[.=$indicator]">
<xsl:if test="position()>1">,</xsl:if>
<!--note index in the collection of DATA elements-->
<xsl:variable name="this-role"><xsl:number/></xsl:variable>
<!--use that index in other columns-->
<xsl:value-of select="$production/fm:COL[$crew_name]/
fm:DATA[number($this-role)]"/>
<xsl:if test="$production/fm:COL[$crew_flag]/
fm:DATA[number($this-role)]='Yes'">
<xsl:text>*</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:if>
<xsl:text>&#xa;</xsl:text>
</xsl:template>


</xsl:stylesheet>

T:\ftemp>call xslt eric.xml eric2.xsl eric2.txt

T:\ftemp>type eric2.txt
Title: The Alice
PRDC: Alan Jones,Zachary Azimuth
EXCP: Big Cheese,Little Cheese
DRCT: Bill Smith*
DOPH: Camera Guy
WRTR: Dicky Dickens

Title: Mini Mini
DRCT: Wal Walliams*
PRDC: Wal Walliams*
WRTR: Wal Walliams*

T:\ftemp>type eric2.xsl
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:fm="http://www.filemaker.com/fmpxmlresult"
                version="1.0">

<xsl:output method="text"/>

<xsl:variable select="1"  name="title_id" />
<xsl:variable select="2"  name="title" />
<xsl:variable select="3"  name="crew_role" />
<xsl:variable select="4"  name="crew_name" />
<xsl:variable select="5"  name="crew_flag" />

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

<xsl:template match="fm:ROW">
  <xsl:if test="position()>1"><xsl:text>&#xa;</xsl:text></xsl:if>
  <xsl:text>Title: </xsl:text>
  <xsl:value-of select="fm:COL[$title]/fm:DATA"/>
  <xsl:text>&#xa;</xsl:text>
  <xsl:variable name="production" select="."/>
  <xsl:variable name="role" select="fm:COL[$crew_role]/fm:DATA"/>
  <xsl:for-each select="$role">
    <xsl:if test="generate-id(.)=
                  generate-id($role[.=current()][1])">
      <xsl:call-template name="do-role">
        <xsl:with-param name="indicator" select="."/>
        <xsl:with-param name="production" select="$production"/>
      </xsl:call-template>
    </xsl:if>
  </xsl:for-each>
</xsl:template>

<xsl:template name="do-role">
  <xsl:param name="indicator"/>
  <xsl:param name="production"/>
  <xsl:if test="$production/fm:COL[$crew_role]/fm:DATA[.=$indicator]">
    <xsl:value-of select="$indicator"/>
    <xsl:text>: </xsl:text>
    <!--find all-->
    <xsl:for-each select="$production/fm:COL[$crew_role]/
                          fm:DATA[.=$indicator]">
      <xsl:if test="position()>1">,</xsl:if>
      <!--note index in the collection of DATA elements-->
      <xsl:variable name="this-role"><xsl:number/></xsl:variable>
      <!--use that index in other columns-->
      <xsl:value-of select="$production/fm:COL[$crew_name]/
                            fm:DATA[number($this-role)]"/>
      <xsl:if test="$production/fm:COL[$crew_flag]/
                    fm:DATA[number($this-role)]='Yes'">
        <xsl:text>*</xsl:text>
      </xsl:if>
    </xsl:for-each>
  </xsl:if>
  <xsl:text>&#xa;</xsl:text>
</xsl:template>

</xsl:stylesheet>

T:\ftemp>rem Done!



--
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@xxxxxxxxxxxxxxxxxxxx
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

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.