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