user3545403
user3545403

Reputation: 11

xslt issue - selecting until preceding-sibling changes

I know its been asked before but I'm struggling to get the xpath correct for my scenario: I want to get the the correct users for a given customer:

<root>

<div>
<span>customer1</span>
</div>
<div><img></img></div>
<div>userForCustomer1</div>
<div>anotherUserForCustomer1</div>

<div>
<span>customer2</span>
<div><img></img></div>
</div>
<div>userForCustomer2</div>
<div>anotherForCustomer2</div>

<div>
<span>customer3</span>
<div><img></img></div>
</div>
<div>userForCustomer3</div>
<div>anotherForCustomer3</div>

</root>

using the following xpath, I am getting the next set of users:

//div[span='customer2']/following-sibling::div[preceding-sibling::div/span = 'customer2']

gives us

<div>userForCustomer2</div>

<div>anotherForCustomer2</div>

<div>
<span>customer3</span>
<div>
<img/>
</div>
</div>

<div>userForCustomer3</div>

<div>anotherForCustomer3</div>

and if I try to stop it going to far with:

//div[span='customer2']/following-sibling::div[preceding-sibling::div[1]/span = 'customer2']

gives us

<div>userForCustomer2</div>

it just returns the 1 user, not both users for customer2

what I am after is:

<div>userForCustomer2</div>
<div>anotherForCustomer2</div>

I'm sure its an easy answer.

Thanks in advance

========================

Update:

//div[span='customer2']/following-sibling::div[preceding-sibling::div[span][1]/span= 'customer2']

Gets us very close with this result:

<result>
<div>userForCustomer2</div>

<div>anotherForCustomer2</div>

<div>
<span>customer3</span>
<div>
<img/>
</div>
</div>

</result>

but I guess I need to now trim the divs I dont want such as the one with the img and with customer3 in

Upvotes: 1

Views: 64

Answers (1)

Ian Roberts
Ian Roberts

Reputation: 122414

Your approach is almost correct, you just need to look at

preceding-sibling::div[span][1]

(the nearest preceding div-with-a-span) instead of

preceding-sibling::div[1]

(the nearest preceding div, whether it has a span child or not).

But personally I would approach this in XSLT with a key that links each div-without-a-span to its customer name:

<xsl:key name="userByCustomer" match="div[not(span)]"
         use="preceding-sibling::div[span][1]/span" />

Now given a particular customer name you can extract all the relevant users with a single function call

<xsl:copy-of select="key('userByCustomer', 'customer2')" />

Upvotes: 0

Related Questions