views:

64

answers:

2

Hi, i have a problem with a xpath-statement.

Basically, the problem can be explained at the following code:

<xsl:for-each select="/b1im:B1IMessage/b1im:Header/b1im:Z/SortInbound/group">
                    <!-- Check if entry from duplicate table is found for the current AccountingEntry -->
                    <xsl:variable name="externalId" select="../externalId"></xsl:variable>
                    <xsl:value-of select="/b1im:B1IMessage/b1im:Body/b1im:Payload[@ObjectRole=&apos;CA&apos;]/jdbc:SqlResult/jdbc:ResultSet/jdbc:Row[jdbc:external_id= /../externalId]/jdbc:external_id"></xsl:value-of>
                    <xsl:variable name="group" select="./@id"></xsl:variable>                        
                    <!-- if it is no dupe => output -->
                     <xsl:choose>
                            <xsl:when test="/b1im:B1IMessage/b1im:Body/b1im:Payload[@ObjectRole=&apos;CA&apos;]/jdbc:SqlResult/jdbc:ResultSet/jdbc:Row[jdbc:external_id = ../externalId]/jdbc:external_id">

What I want to do is, use the value of "../externalId" (context of for-each) for a test (last line).. It would work if I used a variable ($externalId), but the variable is only set once (first loop iteration)... Is there a way how i can access the for-each-context in the xpath-expression?

Thanks in advance!! Tobias

+2  A: 

On each step of XPath evaluation, the "." (i.e. context node) has different meaning. In your XPath expression
... jdbc:ResultSet/jdbc:Row[jdbc:external_id = ../externalId] the context node in the predicate is determined by the previous steps in your XPath expression, so you are actually comparing to externalID child of the jdbc:ResultSet element. To compare to the value of ../externalID of the for-each context node you could try using XSLT function current().

... jdbc:ResultSet/jdbc:Row[jdbc:external_id = current()/../externalId]

jasso
+1  A: 

Two issues.

First, as @jasso has answered, when evaluating predicates the context is determined by last step. From http://www.w3.org/TR/xpath/#predicates

A predicate filters a node-set with respect to an axis to produce a new node-set. For each node in the node-set to be filtered, the PredicateExpr is evaluated with that node as the context node, with the number of nodes in the node-set as the context size, and with the proximity position of the node in the node-set with respect to the axis as the context position

Second. You wrote:

It would work if I used a variable ($externalId), but the variable is only set once (first loop iteration)...

That's not true. The for-each content template is instantiated once for every node in its selected node set. Thus, externalId gets evaluate once for each of such nodes.

So, the right answer from @jasso:

... jdbc:ResultSet/jdbc:Row[jdbc:external_id = current()/../externalId]

Is the same as:

... jdbc:ResultSet/jdbc:Row[jdbc:external_id = $externalId]
Alejandro
@Alejandro, Good answer +1. In practice, when you have answered a question, I rarely haveto add anything to yoyr answer.
Dimitre Novatchev
@Dimitre: Ja! Thanks! The same happens to me. ;)
Alejandro
Thanks to both of you, got it to work :) the method with the variable didn't worked for me in the first place because i had a fault in my input-xml.. Nevertheless, good to know the current()-function! Thanks
Tobias Viehweger