RE: [xsl] Using id() when id and idref are in 2 different files

Subject: RE: [xsl] Using id() when id and idref are in 2 different files
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Mon, 13 Dec 2004 11:17:43 -0000
The id() function searches the document that contains the context node. This
doesn't have to be the same document as contains the idref; but it is always
a single document. In 2.0 you can supply a second argument that indicates
which document to search, but it still searches only a single document. This
is because XML IDs are scoped to a single document.

The key() function is also scoped to a single document, so this doesn't help
you much. The only way to search across multiple documents is to use a
filter expression, which is likely to be expensive. The alternative is to
combine the data into a single document simply so that you can use id() or
key().

You could try building a mapping table (as a temporary tree) that maps ids
to the document containing them, and then do a two-stage lookup, first using
the key() function to access an entry in this mapping table, and then using
the id() function within the identified document. You would need some kind
of identifier for each document, the simplest being the URI that was used to
retrieve it in the first place.

Michael Kay
http://www.saxonica.com/ 

> -----Original Message-----
> From: Chris Matchett [mailto:matchett79@xxxxxxxxxxx] 
> Sent: 13 December 2004 10:33
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] Using id() when id and idref are in 2 different files
> 
> This is my first posting and I'm sorry if this has been 
> answered many times.
> I've tried searching on the archive, Google and so on, but 
> it's tricky when
> I have such a hard time even describing my problem.
> 
> I'm trying to work out how to use id() when the ID values are 
> in a different
> xml file from the one where the IDREFS are. I've been given 
> the task of
> converting a play into xml. To avoid having one long file 
> I've decided to
> split the acts into separate files and link to them from a 
> title page that
> contains the titles and cast list.
>  
> The cast list contains role elements: <!ELEMENT role 
> (#PCDATA)*> <!ATTLIST
> role id ID #REQUIRED>
> The other files have various elements that refer to these 
> actors using @who
> which is an IDREF e.g.: <!ELEMENT speech (#PCDATA)> <!ATTLIST 
> speech who
> IDREFS #IMPLIED>
> 
> Using <xsl:template match="speech">
> 		<xsl:value-of select="id(@who)" />:
> 		<blockquote> Alas! Poor Yorick...
> works fine if everything is in one file but of course when 
> the IDs are no
> longer there it fails.
> 
> So I have tried using document() to read the castlist into a 
> variable called
> $cast. Now I can use <xsl:value-of select="$cast//@id" /> to 
> output the
> required values but I can't get it to work with the id()function.
> <xsl:value-of select="id(@who)" /> just fails, which doesn't 
> surprise me.
> However <xsl:value-of select="$cast//role[@id = @who]" /> also returns
> nothing. Is it because it is now looking for @who within $cast?
> 
> <xsl:value-of select="$cast//role[@id = 'r1']" /> will return 
> the value that
> has an @id of "r1" so I guess I'm almost there. But that's 
> where I have been
> stuck for the past few days. I've also tried reading @who into a $who
> variable and using that but that makes no difference.
> 
> I'm using the Xalan.jar parser. Hope someone can help and I 
> hope this isn't
> too newbie-ish.
> 
> Chris Matchett
> IT Monkey and Birkbeck Student

Current Thread