Spectraljump
Spectraljump

Reputation: 4647

XSLT key element: "use" parent node of the "match"

I can't seem to figure this thing out. Is it at all possible to have the following key?

<xsl:key name="kMatchSentenceID_withTokId" match="sentences/sentence/@ID"
         use="--and here return the 'sentences' node--"/>

I don't get how "use" works, isn't it supposed to be a value that you return when the match was matched?

I see that use="." returns the value of the attribute in my case. (Why? Is it linked to the match? Shouldn't . mean node()? and not node()/@)

But most importantly, how come I can't do something like this: use="parent::sentence[@ID=name()]"

How would I go about doing this then? I need a match on the @ID, but to return it's parent (more specifically, the parent's ID).

Thank you.

Upvotes: 3

Views: 2500

Answers (3)

Wayne
Wayne

Reputation: 60424

I don't get how "use" works, isn't it supposed to be a value that you return when the match was matched?

No, use does not specify anything to be "returned". From the spec:

The use attribute is an expression specifying the values of the key; the expression is evaluated once for each node that matches the pattern.

In a mapping of keys to values use specifies the keys -- the values of the key, in the spec's language -- and match specifies the values that those keys will map to. In other words, match specifies what to group and use specifies how to group them .

Say you wanted to group sentence elements by the @ID of their parent sentence. You could do that like this:

<xsl:key name="kMatchSentenceID_withTokId" match="sentences/sentence" 
         use="parent::*/@ID"/>

Your expression makes no sense:

<xsl:key name="kMatchSentenceID_withTokId" match="sentences/sentence/@ID"
         use="parent::sentence[@ID=name()]"/>

...because it's trying to group the ID attributes by one of their parent sentence elements, which is already a mistake, since attributes don't have parents.

Upvotes: 3

Michael Kay
Michael Kay

Reputation: 163625

It's a bit difficult to help you since you don't actually say what problem you're trying to solve. But you seem to have some conceptual confusion about keys. Think of them this way: if you want to find the E elements that have the value V for their property P, then you need to define the key as <xsl:key name="N" match="E" use="P"/> where P is an XPath expression which, using an E element as its context, determines the value of the property in question; and then you need to call it as key('N', V). The use expression can be any XPath expression you like, and it will be evaluated using the matching E element as its context item.

The examples you've given seem to be legal but not very useful; it's not clear what you were hoping they would do.

Upvotes: 1

Emiliano Poggi
Emiliano Poggi

Reputation: 24836

Assuming something like this

<sentences id="parent">
  <sentence id="childa"/>
  <sentence id="childb"/>
</sentences>

You need:

<xsl:key name="sentence" match="sentences" use="sentence/@id"/>

Then, for example the XPathkey('sentence','childa')/@id would return 'parent'.

Upvotes: 1

Related Questions