Re: [xsl] Joining xml documents on the fly

Subject: Re: [xsl] Joining xml documents on the fly
From: Lars Huttar <lars_huttar@xxxxxxx>
Date: Mon, 08 Jun 2009 09:56:32 -0500
On 6/8/2009 9:43 AM, Joelle Tegwen wrote:
> Ok, now I've got a new twist on the same type of data set.
> 
> Now I want to find all of the people in <project_staff_roles> who are
> listed more than, arbitrarily, 5 times.
> 
> I get somewhere around this:
>    <xsl:variable name="common"
>       
> select="$project_staff_roles/project_staff_role/@staff_id[count($project_staff_roles/project_staff_roles/@staff_id
> = .) > $common_count]"/> and of course this doesn't work.

If you change
	project_staff_roles/@staff_id
to
	project_staff_role/@staff_id
(remove the extra 's') does it work? Seems like it should.

Of course that will give you a nodeset of staff id's, and each one in
the set will be repeated at least $common_count + 1 times, and the
repeats for different people will be mixed.

If you're using XSLT 2.0 you could do something like

for-each-group select="project_staff_roles/project_staff_role"
   group-by="@staff_id"
  if test="count(current-group()) > $common_count"
    value-of select="current-group()[1]/@staff_id"

That would give you each staff_id only once.

Lars

> 
> I'm sorry, I'm just really struggling with the underlying concepts here.
> I think I'm trying to approach this from an SQL point of view and I'm
> just not able to re-frame my thought process correctly.
> 
> Thanks much again.
> Joelle
> 
> Joelle Tegwen wrote:
>> Ok, I'm in totally over my head here. I'm hoping someone can help me out.
>>
>> I've got 2 external (reference) documents I'm including into my
>> stylesheet.
>>
>> One is a list of staff. It looks like this (edited for brevity):
>>
>> <people>
>>    <staff staff_id="123456789" alpha_key="A" sort_key="AberyBrian">
>>        <display_name>Brian H Abery</display_name>
>>    </staff>
>>    <staff staff_id="987654321" alpha_key="A" sort_key="AlbusDeb">
>>        <display_name>Deb Albus</display_name>
>>    </staff>
>>    <staff staff_id="456321789" alpha_key="A" sort_key="AltmanJason">
>>        <display_name>Jason R Altman</display_name>
>>    </staff>
>> </people>
>>
>> And the other is the three way join between staff, projects and roles
>> <project_staff_roles>
>>    <project_staff_role project_id="1" staff_id="123456789"
>> role_id="staff">
>>        <staff staff_id="123456789" alpha_key="A" sort_key="AberyBrian">
>>            <display_name>Brian H Abery</display_name>
>>        </staff>
>>    </project_staff_role>
>>    <project_staff_role project_id="1" staff_id="123456789"
>> role_id="director">
>>       <staff staff_id="123456789" alpha_key="A" sort_key="AberyBrian">
>>            <display_name>Brian H Abery</display_name>
>>        </staff>
>>    </project_staff_role>
>>    <project_staff_role project_id="2" staff_id="987654321"
>> role_id="staff">
>>        <staff staff_id="987654321" alpha_key="A" sort_key="AlbusDeb">
>>            <display_name>Deb Albus</display_name>
>>        </staff>
>>    </project_staff_role>
>> </project_staff_roles>
>>
>> I want to break this into two groups based on the current project_id.
>> So if I'm viewing project_id=1
>> I want two groups of people
>>
>> Project Staff:
>> <people>
>>    <staff staff_id="123456789" alpha_key="A" sort_key="AberyBrian">
>>        <display_name>Brian H Abery</display_name>
>>    </staff>
>> </people>
>>
>> Non-Project-Staff
>> <people>
>>    <staff staff_id="987654321" alpha_key="A" sort_key="AlbusDeb">
>>        <display_name>Deb Albus</display_name>
>>    </staff>
>>    <staff staff_id="456321789" alpha_key="A" sort_key="AltmanJason">
>>        <display_name>Jason R Altman</display_name>
>>    </staff>
>> </people>
>>
>> I've got the following variables in my document:
>> <xsl:variable name="staff" select="document($ref_staff)/people"/>
>> <xsl:variable name="staff_roles"
>> select="document($ref_project_staff_role)/project_staff_roles/project_staff_role[@role_id='staff']"/>
>>
>> <xsl:variable name="project_staff"
>> select="$staff_roles[@project_id=$[project_id]/staff"/>
>> <xsl:variable name="non_project_staff" select="?????"/>
>>
>> How do I even go about thinking about this? I've tried googling it but
>> I have no idea what to search on. I've tried various iterations of
>> keys, etc but I just can't get it.
>>
>> The final xslt that gives the desired output is:
>>         <xsl:if test="count($project_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="$project_staff"/>
>>                </xsl:call-template>
>>            </fieldset>
>>        </xsl:if>
>>              <xsl:if test="count($non_project_staff) > 0">
>>            <fieldset class="span-18 last col-wrap">
>>                <legend class="quiet">All Other People</legend>
>>                <div id="tabs">
>>                    <ul>
>>                        <xsl:for-each
>>                           
>> select="$staff/staff/@alpha_key[generate-id()=generate-id(key('alpha',
>> .))]">
>>                            <xsl:if
>> test="count($non_project_staff[@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
>>                       
>> select="$staff/staff/@alpha_key[generate-id()=generate-id(key('alpha',
>> .))]">
>>                        <xsl:if
>> test="count($non_project_staff[@alpha_key = current()]) > 0">
>>                            <xsl:call-template name="tab_data">
>>                                <xsl:with-param name="alpha_string"
>> select="."/>
>>                                <xsl:with-param name="objects"
>>                                   
>> select="$non_project_staff[@alpha_key = current()]"/>
>>                            </xsl:call-template>
>>                        </xsl:if>
>>                    </xsl:for-each>
>>                </div>
>>                          </fieldset>
>>        </xsl:if>
>>
>>
>> I hope this is clear. Any help would be much appreciated.
>>
>> Thanks in advance.
>> Joelle

Current Thread