Question: I want to eliminate some duplicated code. Can anyone make this code shorter and better?

```
switch (now.site)
{

    case item.SITE.AMAZON:
        try
        {
            price = driver.FindElement(By.XPath("//*[@id=\"priceblock_ourprice\"]")).Text;
            fetched = true;
        }
        catch
        {
            try
            {
                price = driver.FindElement(By.XPath("//*[@id=\"priceblock_dealprice\"]")).Text;
                fetched = true;
            }
            catch
            {
                fetched = false;
            }
        }
        break;
    case item.SITE.ALI:
        try
        {
            price = driver.FindElement(By.XPath("//*[@id=\"j-sku-discount-price\"]")).Text;
            fetched = true;
        }
        catch
        {
            try
            {
                price = driver.FindElement(By.XPath("//*[@id=\"j-sku-price\"]")).Text;
                fetched = true;
            }
            catch
            {
                fetched = false;
            }
        }
        break;
    }
}

```

Answer: 
It appears that you're really trying to get a decimal value. Let's use this assumption and make a method that returns a `decimal?` to indicate success (i.e. a value) or failure (i.e. `null`).

```
public static class Ex
{
    public static decimal? FindDecimalMaybe(this IWebDriver driver, string path)
    {
        try
        {
            if (decimal.TryParse(driver.FindElement(By.XPath(path)).Text, out decimal result))
            {
                return result;
            }
        }
        catch { } // I hate this, but there doesn't seem to be a choice
        return null;
    }
}

```

The purpose of this method is to hide the unpleasant fact that the Selenium library appears to code by exception.

I've also created it as an extension method so that the call to `driver.FindElement` is replaced by something that looks familiar - `driver.FindDecimalMaybe`.

Now I take the same approach as Oliver with a dictionary:

```
private static Dictionary<string, string[]> __pricePaths = new Dictionary<string, string[]>
{
    { item.SITE.AMAZON, new [] { "//*[@id=\"priceblock_ourprice\"]", "//*[@id=\"priceblock_dealprice\"]" } },
    { item.SITE.ALI, new [] { "//*[@id=\"j-sku-discount-price\"]", "//*[@id=\"j-sku-price\"]" } },
};

```

Now it's trivial to get the values out:

```
decimal? price =
    __pricePaths[now.site]
        .Select(path => driver.FindDecimalMaybe(path))
        .Where(x => x.HasValue)
        .FirstOrDefault();

```

If the `price` variable has a value then success, but if it is `null` then the call did not succeed.
Here are some recommendations as to how you can beautify your code - 

1. Declare constants for all XPath queries.
2. Declare a variable outside the switch statement to capture the price value based on your case statement.
3. Create a function with one try catch statements which accepts 2 xPath strings and an out parameter for Price and returns a boolean value to indicate if the query was successful.
4. Remove the try catch from under each case and call that function passing the correct xPath strings from the set of constants.

```
const string priceblock_ourprice = "//*[@id=\"priceblock_ourprice\"]";
const string priceblock_dealprice = "//*[@id=\"priceblock_dealprice\"]";
const string j_sku_discount_price = "//*[@id=\"j-sku-discount-price\"]";
const string j_sku_price = "//*[@id=\"j-sku-price\"]";

public void YourPrimaryFunction
{  
    decimal price;  
    switch (now.site)  
    {  
        case item.SITE.AMAZON:  
            fetched = FetchPrice(priceblock_ourprice, priceblock_dealprice, out price);
            break;  
        case item.SITE.ALI:  
            fetched = FetchPrice(j_sku_discount_price, j_sku_price, out price);
            break;
    }
}

private bool FetchPrice(string xPathPrim, string xPathFallBack, decimal out price)
{
    try
    {
        price = driver.FindElement(By.XPath(xPathPrim)).Text;
        return true;
    }
    catch
    {
        try
        {
            price = driver.FindElement(By.XPath(xPathFallBack)).Text;
            return true;
        }
        catch
        {
            return false;
        }
    }
}

```