Kallol
Kallol

Reputation: 364

Xpath "preceding" check to find value

The html on which the Xpath is being applied is kind of long and hence pasting the link to the page on which the Xpath needs to be fired.

http://www.amazon.com/Greatest-Hits-More-Dr-Hook/dp/B003ANZBD0/ref=sr_1_1?ie=UTF8&qid=1424511706&sr=8-1&keywords=B003ANZBD0

I want to get the "Buy New" price of an item only if the item is "Fulfilled By Amazon".

I am using Html Agility Pack on C#.

Here is my attempt. I first try to see if the item is fulfilled by Amazon. //div[@id='buyNewInner']//descendant::a[contains(@href,'isAmazonFulfilled=1')]

But I dont know how to continue from here to go to the preceding nodes and get the price of the item, in this case $99.99

Intention is not only have a single Xpath to get this price but also ensure I avoid as much as assumption possible on position of various nodes relative to each other and try to match w.r.t visible text rather than Html node positioning like div//span[1]. (Here the Xpath signifies match with first span - which I am trying to avoid if possible)

So in this case, the logic for matching I am trying to achieve is:

Find the price following the words "Buy New" provided this occurs before the words "FulFillment By Amazon"

Upvotes: 1

Views: 207

Answers (2)

har07
har07

Reputation: 89285

This is one possible XPath (formatted for readability), constructed based on your attempt to check whether the item is fulfilled by Amazon.

//div[
        @id='buyNewInner' 
            and 
        .//descendant::a[contains(@href,'isAmazonFulfilled=1')]
     ]
/preceding-sibling::div[@id='buyNewSection']
//span[contains(@class,'offer-price')]

First part of the XPath returns <div id="buyNewInner"> element only if the item is "Fulfilled By Amazon" :

//div[
        @id='buyNewInner' 
            and 
        .//descendant::a[contains(@href,'isAmazonFulfilled=1')]
     ]

The next bit returns <div id="buyNewSection"> which assumed to be located before buyNewInner div at the same level, hence we use preceding-sibling :

/preceding-sibling::div[@id='buyNewSection']

Then the last part goes straight to the <span> containing the item price :

//span[contains(@class,'offer-price')]

Upvotes: 2

Loic Dachary
Loic Dachary

Reputation: 1084

You need to use .. to go back to the father of the node. Using the example page you gave, adding ../../../../div[@id='buyNewSection'] brings you to the sibling div that you need. The XPath:

//div[@id='buyNewInner']//descendant::a[contains(@href,'isAmazonFulfilled=1')]/../../../../div[@id='buyNewSection']//span[contains(@class,'offer-price')]

will display

$99.99

Upvotes: 0

Related Questions