xsl-list
[Top] [All Lists]

Re: use of xsl:key in cross-referencing

2003-03-26 16:52:21
Dear Wendell:

  Thank you for your reply.  Your solution could have
solved my problem as well, the essence is similar to
Lars' soltuion which is if creating a key with the
same name using two different groups that key off
different elements, then I need to use different match
pattern for the two different groups.  The difference
is your solution separated the groups by cell, and
Lars solution used row.

Thanks for the help, much appreciated.
Xiaocun

--- Wendell Piez <wapiez(_at_)mulberrytech(_dot_)com> wrote:
Xiaocun,

Sorry I've been off the list-- out here in the hills
of WV, my phone line 
is down, and I have to hoof it to my neighbor's to
get a net connection.

Anyhow, you are pretty close to your solution:

<xsl:key name="QuestionnaireKey"
  match="row[count(cell)=3]/cell[2]"
  use="."/>

<xsl:key name="QuestionnaireKey"
  match="row[count(cell)=2]/cell[1]"
  use="."/>

Instead of recognizing the different groups by their
row number, I decided 
to use the count of their cells. If I have three
cells, I know this is a 
row like

<row row="17">
   <cell column="1">Questionnaire B</cell>
   <cell column="2">QB</cell>
   <cell column="3">Questionnaire B, empty with no
questions</cell>
</row>

and the Questionnaire identifier is the second cell
(whose value is 'QB').

If I have only two cells, however, my data is like
this

<row row="28">
   <cell column="1">QA</cell>
   <cell column="2">Questionnaire A, Question
2</cell>
</row>

and the identifier is the first cell (value is
'QA').

If this assumption does not hold for your data, you
need to adjust the 
match patterns in the key declarations to whatever
does work.

On the data as you provided it, the Questionnaire
key retrieves either one 
of these kinds of identifiers by the correct value
('QA', 'QB' or 'QC').

Then if I have

<xsl:template match="/">
   <xsl:apply-templates
     select="//cell[key('QuestionnaireKey',.) and
                   
count(.|key('QuestionnaireKey',.)[1])=1 ]"/>
</xsl:template>

I select

//cell   ... all the cells in the document...

[key('QuestionnaireKey',.)
... testing whether this cell's value is among my
Questionnaire identifiers 
(note this introduces a very subtle assumption about
these identifiers, 
namely that they are unique strings) ...

and count(.|key('QuestionnaireKey',.)[1])=1 ]
... making sure if it is an identifier, it's the
first one (Muenchian 
grouping).

I think you can see this is a cleaned-up version of
what you almost had....

Cheers,
Wendell

At 06:36 PM 3/20/2003, you wrote:
Hi, Wendell:

Thanks for the idea of define two keys for the two
groups with the same name but different "use"
value,
but I was unable to find anything in regard to it
at
Jenni's website, xsl-list archive (using keywords
"two
key;same name;") or google web/group.  I did some
thinking myself and still don't see how that works.
Following is an example, having rows 10-19 being
the
first group (Questionnaire) and 20-29 being the
second
group (Question):
<range>
<row row="16">
        <cell column="1">Questionnaire A</cell>
        <cell column="2">QA</cell>
        <cell column="3">Questionnaire A, two
questions</cell>
</row>
<row row="17">
        <cell column="1">Questionnaire B</cell>
        <cell column="2">QB</cell>
        <cell column="3">Questionnaire B, empty
with no
questions</cell>
</row>

<row row="27">
        <cell column="1">QA</cell>
        <cell column="2">Questionnaire A, Question
1<cell>
</row>
<row row="28">
        <cell column="1">QA</cell>
        <cell column="2">Questionnaire A, Question
2</cell>
</row>
<row row="29">
        <cell column="1">QC</cell>
        <cell column="2">Questionnaire C, Question
1</cell>
</row>
</range>

In this case, questionnaire QA has two questions,
QB
is only referred in the 1st group and QC is only
referred in the 2nd group.  What I need is to be
able
to process each of QA/QB/QC.

To define two keys for the two groups with the same
name but different "use":
<xsl:key name="QuestionnaireKey" match=//row[(_at_)row
&lt;
20]" use="string(cell[(_at_)column=2])"/>
<xsl:key name="QuestionnaireKey" match=//row[(_at_)row
&gt;
20]" use="string(cell[(_at_)column=1])"/>

Use Muenchian method to process each just once, for
the 2nd group:
<xsl:apply-templates select="//row[(_at_)row &gt; 20 and
@row &lt; 30][count(.|key('QuestionnaireKey',
string(cell[(_at_)column=1]))[1]) = 1]"/>
but this will miss questionnaire QC.

I guess to take advantage of the combined key, I
need
to do select on all rows, like:
<xsl:apply-templates
select="//row[count(.|key('QuestionnaireKey',
string(cell[(_at_)column=1]))[1]) = 1]"/>
Would the above work?  If so, how can I tell if the
row being processed is from group 1 (Questionnaire)
or
2 (Question)?


___&&__&_&___&_&__&&&__&_&__&__&&____&&_&___&__&_&&_____&__&__&&_____&_&&_
     "Thus I make my own use of the telegraph,
without consulting
      the directors, like the sparrows, which I
perceive use it
      extensively for a perch." -- Thoreau


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



__________________________________________________
Do you Yahoo!?
Yahoo! Platinum - Watch CBS' NCAA March Madness, live on your desktop!
http://platinum.yahoo.com

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