xsl-list
[Top] [All Lists]

Re: use of xsl:key in cross-referencing

2003-03-15 16:35:14
Xiaocun Xu wrote:
Hi, All:

I have a problem related to cross referencing.

I have two groups of <row> elements in which the first
group are questionnaires and second group are
questions within the questionnaires (defined in the
first group).  The first <cell> element of the
question group cross references to the second <cell>
element of the questionnaire group.  For example, the
below XML, row 28 and 29 cell 1 "References" cross
references to row 16 cell 2.
<row row="16">
        <cell column="1">References Name</cell>
        <cell column="2">References</cell>
        <cell column="3">References Description</cell>
</row>
...<rows in between skipped for brevity>...
<row row="28">
        <cell column="1">References</cell>
        <cell column="2">text of Question 8<cell>
</row>
<row row="29">
        <cell column="1">References</cell>
        <cell column="2">text of Question 9</cell>
</row>
Relationship of questionnaire to question is one to
many, so each questionnaire should appear only once in
the 1st group; but in the 2nd group, multiple
questions could refer to the same questionnaire.

The way I currently handles it is create a xsl:key
matching rows in the 2nd group (questions) using the
1st cell.  When I process the 1st group of rows
(questionnaires), I call key() function by passing in
the value in the 2nd cell.  The problem with this
approach is that it ignores question with a
questionnaire not defined in the 1st group.  Is there
an elegant way to address this problem?

Yes, XML has a built-in cross-reference mechanism which uses special attribute types called ID and IDREF. If you modify your DTD:

<!ELEMENT cell (#PCDATA)>
<!ATTLIST cell column CDATA #REQUIRED
               questionnaire ID #IMPLIED
               question IDREF #IMPLIED>

Now you can say:

<row row="16">
        <cell column="1">References Name</cell>
        <cell column="2" questionnaire="ABC123">References</cell>
        <cell column="3">References Description</cell>
</row>
...<rows in between skipped for brevity>...
<row row="28">
        <cell column="1" question="ABC123">References</cell>
        <cell column="2">text of Question 8<cell>
</row>
<row row="29">
        <cell column="1" question="ABC123">References</cell>
        <cell column="2">text of Question 9</cell>
</row>

The ID/IDREF mechanism is one-to-many, so if I have understood you
right, this is what you want. The advantage is that ID/IDREF checking
is built into validating parsers, so a validation will immediately
pick up on any IDREF attribute trying to reference a non-existent ID
value (but it's OK to have an ID value which never gets referenced).
The only restriction is that ID/IDREF values must be Names (they must
begin with a letter and may not contain spaces).

///Peter



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