Re: [xsl] IDREFS and key()

Subject: Re: [xsl] IDREFS and key()
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Mon, 28 Nov 2005 22:49:53 -0500
At 2005-11-28 18:30 -0800, Dan Vint wrote:
I have an element that contains an IDREFS attribute like the following:

<Attribute id="aAtt" references="foo bar"><Name>Att</Name></Attribute>

The references attribute is defined as an IDREFS and the schema and document that this lives in are all valid.

I want to use the references attribute in a key definition so I can reverse the relationship and in this case from the element identified as foo or bar, indicate that the Attribute element, named Att links to it.

My key definition is this:

<xsl:key name="attribute-references" match="Attribute" use="@references"/>

You've got this backwards ... but even straightening it out won't help you with ID/IDREFS. You load key tables with the nodes being looked up, not with the nodes with the lookup values.

When mimicking ID/IDREF (not ID/IDREFS) you can load the key table with <xsl:key> matching the elements with the id= attribute using the value of the id= attribute, and then use the key() function with the IDREF attribute for the lookup.

But it doesn't work for ID/IDREFS, only for mimicking ID/IDREF.

It seems like the key() is trying to match my value of 'foo' against the complete string of 'foo bar', rather than doing a "contains" sort of match.

Indeed it is, by definition.

Is this what is expected?


When I provide the full 'foo bar' to the for-each I now match this Attribute definition.

As it should.

How do I get the key() function to break up the IDREFS

You can't in XSLT 1.0.

and process the individual values? I tried using id() in the key definition but that didn't help.

Right ...

But the id() function *would* work if you had the luxury of declaring the ID-typed attribute of the elements with the id= attributes:

<!ATTLIST element-name-here id ID #IMPLIED>

This can go in the internal declaration subset of your document, or in an external declaration subset pointed to by the DOCTYPE SYSTEM identifier. Note that you do *not* need the <!ELEMENT> declaration, just the <!ATTLIST> will do. Then you don't even need keys and the id() function will work. I often do this in a chain of transforms by having the output of one transform have the system identifier of a one-line DTD file that has only the ATTLIST declaration.

But not every has the luxury of injecting the attribute list declaration by any means.

I hope this helps.

. . . . . . . . . . Ken

Upcoming XSLT/XSL-FO hands-on courses:  Denver,CO March 13-17,2006
World-wide on-site corporate, govt. & user group XML/XSL training.
G. Ken Holman                 mailto:gkholman@xxxxxxxxxxxxxxxxxxxx
Crane Softwrights Ltd.
Box 266, Kars, Ontario CANADA K0A-2E0    +1(613)489-0999 (F:-0995)
Male Cancer Awareness Aug'05
Legal business disclaimers:

Current Thread