tags:

views:

52

answers:

2

I need to create a cache using an XML file. Here's the method that I will be using. I want this method to return the id based on the key-product_name. So I want it to create a cache one time programmatically and then only if the key is not found then create a [new entry in the] cache. If everything looks okay the problem is getting the id of product. Please advise. I have included the code and xml file.

public static string getProductId(string product_name)
    public static string getTechId(string fieldName)
    {
        Cache cache = HttpContext.Current.Cache;  //neeed to change this.
        string cacheNameEpm = product_name + "PrdName";

        if (cache[cacheNameEpm] == null)
        {
            XPathDocument doc = new XPathDocument(HttpContext.Current.Request.MapPath("inc/xml/prd.xml"));
            XPathNavigator navigator = doc.CreateNavigator();
            string selectName = "/Products/Product/ProductName";
            XPathNodeIterator nodes = navigator.Select(selectName);

            while (nodes.MoveNext())
            {
                switch (nodes.Current.Name)
                {
                    case "ProductName":
                        cacheNameEpm = nodes.Current.Value + "PrdName";
                        navigator.Select("/Products/Product/ProductId");
                        navigator.MoveToNext();
                        if (nodes.Current.Name == "ProductId")
                        {
                            id = navigator.Value;
                        }
                        cache.Add(cacheNameEpm, id, null, DateTime.Now + new TimeSpan(4, 0, 0), System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Default, null);
                        break;
                }
            }
        }

        return cache[cacheNameEpm] as string;
    }

Here is the xml file:

<Products>
    <Product>
        <ProductName>PDPArch</ProductName>
        <ProductId>57947</ProductId>
    </Product>
    <Product>
        <ProductName>TYFTType</ProductName>
        <ProductId>94384</ProductId>
    </Product>
</Products>
A: 

okay. Lets simplify the code. I just want to be able to read the productName and productId into 2 variables. Any ideas how to use Xpath to do that.

sa
A: 

To get the product id of, say, "TYFTType", you would need this XPath expression:

/Products/Product[ProductName = 'TYFTType']/ProductId

So what about something along the lines of (untested, but you get the idea):

public static string getProductId(string product_name)
{
  Cache cache = HttpContext.Current.Cache;

  string cacheNameEpm = product_name + "PrdName";
  if (cache[cacheNameEpm] == null)
  {
    // let's cache the navigator itself as well
    string cacheNameNav = "prd.xml_Navigator";
    XPathNavigator navigator = cache[cacheNameNav] as XPathNavigator;

    if (navigator == null)
    {
      XPathDocument doc = new XPathDocument(
        HttpContext.Current.Request.MapPath("inc/xml/prd.xml")
      );
      navigator = doc.CreateNavigator();
      cache.Add(
        cacheNameNav,
        navigator,
        null,
        DateTime.Now + new TimeSpan(4, 0, 0),
        Cache.NoSlidingExpiration,
        CacheItemPriority.Default,
        null
      );
    }

    string xpath = String.Format(
      "/Products/Product[ProductName = '{0}']/ProductId", product_name
    );

    XPathNavigator product_id = navigator.SelectSingleNode(xpath);

    if (product_id.IsNode)
    {
      cache.Add(
        cacheNameEpm,
        product_id.Value,
        null,
        DateTime.Now + new TimeSpan(4, 0, 0),
        Cache.NoSlidingExpiration,
        CacheItemPriority.Default,
        null
      );
    }
  }

  return cache[cacheNameEpm] as string;
}

The above has two little issues:

  • It will not remember the non-existent product names.
  • Product names must not contain a single quote or the XPath expression will break. You should add a check for this condition.
Tomalak