cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

Community Tip - Stay updated on what is happening on the PTC Community by subscribing to PTC Community Announcements. X

Referencing a variable in XPath

carolynherlin
1-Newbie

Referencing a variable in XPath



Hi Adepters,



I'm having an issue that could be solved by using a variable in XPath, which I don't know how to do, or perhaps by some other means. Here is the situation.



I have an XML that looks like this:



<matching>

<match>

<left>Statement 1a</left>

<right printorder="2">Statement 1b</right>

</match>

<match>

<left>Statement 2a</left>

<right printorder="4">Statement 2b</right>

</match>

<match>

<left>Statement 3a</left>

<right printorder="1">Statement 3b</right>

</match>

<match>

<left>Statement 3a</left>

<right printorder="3">Statement 4b</right>

</match>

</matching>



This is a matching question in which each left element matches with it's sibling right element. However, for presentation, I want to scramble the order of the right answers so that the user has to make a match. To this end, I have a little routine that uses a random number generator to assign the printOrder values.



I am using Styler to make a PDF stylesheet and my idea is to hide the left and right elements, and then use generated text on the match element to create a little two cell table like this (with no lines):






The content of the left child of the context node, i.e. Statement 1a The content of the right child whose printOrder attribute matches the position of the context node, i.e., Statement 3b


I want to do it on the match element rather than just building a four row table at the matching level because the number of match elements can vary.



My problem is with getting the correct right element. I can use ancestor::matching/child::right[@printOrder="x"], where x is the number that corresponds to the position of the original match context node, to get the correct right element. The problem is in getting the value of x. On the match context node, I can use count(preceding-sibling::match)+1 to get the position of the match element. But inserting that in place of x doesn't work because at that point the match element is no longer the context node, and I can't seem to get back to the match element because the context now is some as-yet-unspecified right element.



I would like to be able to store the value of count(preceding-sibling::match)+1 in a variable and then reference it in place of x, but I can't figure out how to do that. Can anyone tell me how to use a variable in this situation or offer an alternative solution?



Thanks,

Carolyn Herlin


4 REPLIES 4

Hi, Carolyn...

As long as you are composing your output with the XSL-FO engine, you might
try the following. Beware, though, that this will cause errors and not
work, if you're using FOSI.

ancestor::matching/match/right[@printOrder =
count(current()/../preceding-sibling::match) + 1]

-Brandon Smiley Happy


On Sat, Sep 18, 2010 at 10:14 AM, Carolyn Herlin
<->wrote:

> Hi Adepters,
>
>
>
> I'm having an issue that could be solved by using a variable in XPath,
> which I don't know how to do, or perhaps by some other means. Here is the
> situation.
>
>
>
> I have an XML that looks like this:
>
>
>
> <matching>
>
> <match>
>
> <left>Statement 1a</left>
>
> <right printorder="2">Statement 1b</right>
>
> </match>
>
> <match>
>
> <left>Statement 2a</left>
>
> <right printorder="4">Statement 2b</right>
>
> </match>
>
> <match>
>
> <left>Statement 3a</left>
>
> <right printorder="1">Statement 3b</right>
>
> </match>
>
> <match>
>
> <left>Statement 3a</left>
>
> <right printorder="3">Statement 4b</right>
>
> </match>
>
> </matching>
>
>
>
> This is a matching question in which each left element matches with it's
> sibling right element. However, for presentation, I want to scramble the
> order of the right answers so that the user has to make a match. To this
> end, I have a little routine that uses a random number generator to assign
> the printOrder values.
>
>
>
> I am using Styler to make a PDF stylesheet and my idea is to hide the left
> and right elements, and then use generated text on the match element to
> create a little two cell table like this (with no lines):
>
>
>
>
> The content of the left child of the context node, i.e. Statement 1a The
> content of the right child whose printOrder attribute matches the position
> of the context node, i.e., Statement 3b
>
>
> I want to do it on the match element rather than just building a four row
> table at the matching level because the number of match elements can vary.
>
>
>
> My problem is with getting the correct right element. I can use
> ancestor::matching/child::right[@printOrder="x"], where x is the number that
> corresponds to the position of the original match context node, to get the
> correct right element. The problem is in getting the value of x. On the
> match context node, I can use count(preceding-sibling::match)+1 to get the
> position of the match element. But inserting that in place of x doesn't work
> because at that point the match element is no longer the context node, and I
> can't seem to get back to the match element because the context now is some
> as-yet-unspecified right element.
>
>
>
> I would like to be able to store the value of
> count(preceding-sibling::match)+1 in a variable and then reference it in
> place of x, but I can't figure out how to do that. Can anyone tell me how to
> use a variable in this situation or offer an alternative solution?
>
>
>
> Thanks,
>
> Carolyn Herlin
>
>
>
>



Hi Brandon,



Thanks for the suggestion, but it didn't work. It returned the value from <right printorder="1"> for all match nodes. I think it is resolving count(current()/../preceding-sibling::match) as 0 and so adding the 1 makes them all come out to value of 1.



Carolyn

I probably wasn't completely clear. That expression was intended to be
evaluated from the context of a "left" or "right" element. If you're
evaluating it in a "match" element, remove the "/.." after "current()".

-Brandon Smiley Happy


On Sun, Sep 19, 2010 at 12:55 AM, Carolyn Herlin
<->wrote:

> Hi Brandon,
>
>
>
> Thanks for the suggestion, but it didn't work. It returned the value from
> <right printorder="1"> for all match nodes. I think it is resolving
> count(current()/../preceding-sibling::match) as 0 and so adding the 1 makes
> them all come out to value of 1.
>
>
>
> Carolyn
>
>



Thanks, Brandon! That did the trick!

Announcements

Top Tags