keys break when using node-set function

Discussion in 'XML' started by Andy Chambers, Mar 7, 2008.

  1. 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?

    --
    Andy
     
    Andy Chambers, Mar 7, 2008
    #1
    1. Advertising

  2. Andy Chambers wrote:

    > 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>


    --

    Martin Honnen
    http://JavaScript.FAQTs.com/
     
    Martin Honnen, Mar 7, 2008
    #2
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    0
    Views:
    1,569
  2. Tjerk Wolterink
    Replies:
    2
    Views:
    1,459
    Dimitre Novatchev
    Aug 24, 2006
  3. Replies:
    0
    Views:
    524
  4. Replies:
    10
    Views:
    736
    Daniel T.
    Feb 3, 2006
  5. Replies:
    12
    Views:
    988
Loading...

Share This Page