xsl-list
[Top] [All Lists]

[xsl] Muenchian method on filtered data set

2009-05-20 10:51:13
I've just recently figured out how to make the Muenchian method work and I've run into a problem that I figured out a way to hack around. It seems rather inelegant so I'm wondering if there's a better way.

I've got an external reference data source that has all of the people in my department and their associate (truncated for simplicity)
<people>
<staff staff_id="unique_id_here" alpha_key="A">
   <name>Fred Anderson</name>
   <associate associate_id="1">
</staff>
<staff staff_id="unique_id_here" alpha_key="A">
   <name>Jane Anderson</name>
   <associate associate_id="2">
</staff>
<staff staff_id="unique_id_here" alpha_key="B">
   <name>Sue Bates</name>
   <associate associate_id="0">
</staff>
<staff staff_id="unique_id_here" alpha_key="B">
   <name>John Boxer</name>
   <associate associate_id="0">
</staff>
....
</people>

It's imported into my document and indexed thusly
   <xsl:variable name="staff" select="document($ref_staff)/people"/>
   <xsl:key name="alpha" match="@alpha_key" use="."/>


When I display them in the form I want to separate them out with preference to a certain associate. In this case, lets say associate_id=1.

In the using the "native" xml I've got a template that looks like this:
   <xsl:template match="people">
       <xsl:variable name="center_staff"
           select="$staff/staff[associate/@associate_id = $associate_id]"/>
<xsl:variable name="other_staff" select="$staff/staff[associate/@associate_id != $associate_id]"/> <xsl:if test="count($center_staff) > 0">
           <fieldset class="span-18 last col-wrap">
               <legend class="quiet">
<xsl:value-of select="ancestor::project/associates/associate/title"/>
                   People</legend>
               <xsl:call-template name="layout_3column">
                   <xsl:with-param name="objects" select="$center_staff"/>
               </xsl:call-template>
           </fieldset>
       </xsl:if>

       <xsl:if test="count($other_staff) > 0">
           <fieldset class="span-18 last col-wrap">
               <legend class="quiet">All other U of M People</legend>
               <div id="tabs">
                   <ul>
                       <xsl:for-each
select="$other_staff/@alpha_key[generate-id()=generate-id(key('alpha', .))]">
                           <xsl:call-template name="tab_link">
<xsl:with-param name="alpha_string" select="."/>
                           </xsl:call-template>
                       </xsl:for-each>
                   </ul>
                   <xsl:for-each
select="$other_staff/@alpha_key[generate-id()=generate-id(key('alpha', .))]">
                       <xsl:call-template name="tab_data">
                           <xsl:with-param name="alpha_string" select="."/>
                           <xsl:with-param name="objects"
select="$other_staff[(_at_)alpha_key = current()]"/>
                       </xsl:call-template>
                   </xsl:for-each>
               </div>
</fieldset>
       </xsl:if>
   </xsl:template>


The problem that I have is that because Fred Anderson is not in the $other_staff node set, the As don't show up at all because the keys don't match.

I debugged this by running the following two snippets:
               <xsl:for-each select="$staff/staff/@alpha_key">
                   <xsl:value-of select="."/> -
                   <xsl:value-of select="generate-id(.)"/> -
                   <xsl:value-of select="generate-id(key('alpha', .))"/>
                   <br/> </xsl:for-each>
<xsl:for-each select="$other_staff/@alpha_key">
                   <xsl:value-of select="."/> -
                   <xsl:value-of select="generate-id(.)"/> -
                   <xsl:value-of select="generate-id(key('alpha', .))"/>
                   <br/> </xsl:for-each>


Which generate:
$staff/staff/@alpha_key:
A - id51618272 - id51618272
A - id51618367 - id51618272
A - id51620641 - id51618272
A - id51620731 - id51618272
A - id51620821 - id51618272

$other_staff/@alpha_key
A - id51618367 - id51618272
A - id51620641 - id51618272
A - id51620731 - id51618272
A - id51620821 - id51618272

None of the keys match for the letter A in the second set because the one that has been keyed is not a member of the set anymore so it's not displayed.

If I change the stylesheet to this it works:
   <xsl:template match="people">
       <xsl:variable name="center_staff"
select="$staff/staff[associate/@associate_id = $associate_id and associate/@associate_id != 0]"/> <xsl:variable name="other_staff" select="$staff/staff[associate/@associate_id != $associate_id or associate/@associate_id = 0]"/> <xsl:if test="count($center_staff) > 0">
           <fieldset class="span-18 last col-wrap">
               <legend class="quiet">
<xsl:value-of select="ancestor::project/associates/associate/title"/>
                   People</legend>
               <xsl:call-template name="layout_3column">
                   <xsl:with-param name="objects" select="$center_staff"/>
               </xsl:call-template>
           </fieldset>
       </xsl:if>
<xsl:if test="count($other_staff) > 0">
           <fieldset class="span-18 last col-wrap">
               <legend class="quiet">All other U of M People</legend>
<div id="tabs">
                   <ul>
                       <xsl:for-each
changed --> select="$staff/staff/@alpha_key[generate-id()=generate-id(key('alpha', .))]"> added --> <xsl:if test="count($other_staff[(_at_)alpha_key = current()]) > 0">
                               <xsl:call-template name="tab_link">
<xsl:with-param name="alpha_string" select="."/>
                               </xsl:call-template>
                           </xsl:if>
                       </xsl:for-each>
                   </ul>
                   <xsl:for-each
changed --> select="$staff/staff/@alpha_key[generate-id()=generate-id(key('alpha', .))]"> added --> <xsl:if test="count($other_staff[(_at_)alpha_key = current()]) > 0">
                           <xsl:call-template name="tab_data">
<xsl:with-param name="alpha_string" select="."/>
                               <xsl:with-param name="objects"
select="$other_staff[(_at_)alpha_key = current()]"/>
                           </xsl:call-template>
                       </xsl:if>
                   </xsl:for-each>
               </div>
</fieldset>
       </xsl:if>
   </xsl:template>



Is there a better way to do this?

Thanks
Joelle

--~------------------------------------------------------------------
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>
  • [xsl] Muenchian method on filtered data set, Joelle Tegwen <=