keys break when using node-set function

A

Andy Chambers

Hi,

I've stumbled across a problem for which I can't find a nice solution
(although it has cleared up a misunderstanding I had about keys).

I've setup keys to access ItemDefs in my document like so...

<xsl:key name="keyItems"
match="odm:ItemDef"
use="concat(ancestor::eek:dm:Study/@OID,
ancestor::eek:dm:MetaDataVersion/@OID, @OID)"/>

Subsequently, I need to build a nodelist of strings with which I can
use to access nodes from this key

<xsl:variable name="xrtFormItems">

<xsl:for-each select="$xnlItemGroups">
<xsl:variable name="xndItemGroupDef"
select="key('keyItemGroups',
concat(ancestor::eek:dm:Study/@OID,
ancestor::eek:dm:MetaDataVersion/
@OID,
@ItemGroupOID))"/>

<xsl:for-each select="$xndItemGroupDef/odm:ItemRef">
<key>
<xsl:value-of select="concat(ancestor::eek:dm:Study/
@OID,

ancestor::eek:dm:MetaDataVersion/@OID,
@ItemOID)"/>
</key>
</xsl:for-each>
</xsl:for-each>
</xsl:variable>

However, if I try to use the values stored in this variable to access
ItemDefs from my key....

<xsl:for-each select="ex:node-set($xrtFormItems)/*">
<xsl:apply-templates select="key('keyItems', .)"/>
</xsl:for-each>

....the key doesn't work. I thought that keys were basically a
hashtable that stored the specified nodes with the use attribute
representing the key. The point being that they were created at the
start and didn't change throughout the process. It seems that doing a
for-each on a node-set returned by some extension function can indeed
change the contents of your keys. Has anyone else bumped into this?
Is it a FAQ? What's the workaround?
 
M

Martin Honnen

Andy said:
However, if I try to use the values stored in this variable to access
ItemDefs from my key....

<xsl:for-each select="ex:node-set($xrtFormItems)/*">
<xsl:apply-templates select="key('keyItems', .)"/>
</xsl:for-each>

...the key doesn't work. I thought that keys were basically a
hashtable that stored the specified nodes with the use attribute
representing the key. The point being that they were created at the
start and didn't change throughout the process. It seems that doing a
for-each on a node-set returned by some extension function can indeed
change the contents of your keys. Has anyone else bumped into this?
Is it a FAQ? What's the workaround?

If you look at <URL:http://www.w3.org/TR/xslt#key> then it says: "A
stylesheet declares a set of keys for each document using the xsl:key
element."
So keys are built for each document and as the nodes you get from
ex:node-set are not part of the same document as the nodes in the input
document your approach above fails.
As a workaround might want to store values in a variable e.g.

<xsl:variable name="main-doc" select="/">

<xsl:for-each select="ex:node-set($xrtFormItems)/*">
<xsl:variable name="el" select="."/>
<xsl:for-each select="$main-doc">
<xsl:apply-templates select="key('keyItems', $el)"/>
</xsl:for-each>
</xsl:for-each>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top