views:

128

answers:

2

I want to filter xml based on query string

my xml is like this

<Categories>   
     <Category>    
       <Title>Food1<Title>  
       <Cat>Cat3</Cat>  
       <Duration>12/1/2009-12/1/2011</Duration>
       <Description>Who is hungry</Description>  
    <Category>
    <Category>    
       <Title>Food1<Title>  
       <Cat>Cat2</Cat>  
       <Duration>12/1/2009-12/1/2011</Duration>
       <Description>Who is hungry</Description>  
    <Category>
    <Category>    
       <Title>Food1<Title>  
       <Cat>Cat1</Cat>  
       <Duration>12/1/2009-12/1/2011</Duration>
       <Description>Who is hungry</Description>  
    <Category>
   <Category>    
       <Title>Food1<Title>  
       <Cat>Cat1</Cat>  
       <Duration>12/1/2009-12/1/2011</Duration>
       <Description>Who is </Description>  
    <Category>

I want filtering based on query string like if

  1. ?food=Food1( it should display all)
  2. ?food=Food1&Cat=Cat1 (it should dispalay last 2)
  3. ?Cat=Cat1&Description=Who is (display last1)
  4. ?food=Food1&Cat=Cat1&Description=Who is hungry(3rd one)

I want to display this in repeater.I am using XPathIterator to iterate it and bind it into repeater.

my code till now is this

  string _Cat = HttpContext.Current.Request.QueryString["Cat"].ToString();
  string _description = HttpContext.Current.Request.QueryString["description"].ToString();
            string _food = HttpContext.Current.Request.QueryString["food"].ToString();


            XmlDocument doc = new XmlDocument();

            doc.Load("/Finder.xml");

            XPathNavigator nav = doc.CreateNavigator();



XPathExpression expression = nav.Compile("/Categories/Category[Cat='_Cat and title='_food' and Description='_description']/*");
 XPathNodeIterator iterator = nav.Select(expression);

//but this will only solve case 4) i know i can write similar for other three but i want this thing to be dynamic. Like we have it in amazon. Filter just add according to the selection u make it.so may there is no query string , may be 1,may be 2 so i need to check on that

and then i m binding this iterator to repeater using datatable

Any idea how to acheive this?

+1  A: 

Have you considered using linq, although I'm not certain to what degree you could avoid repitition

XDocument xmlDoc = XDocument.Load(@"C:\so.xml");

// handle Query String variations here - this works for your first case.
List<Categories> results = (from cats in xmlDoc.Descendants("Category")
                            where cats.Element("Title").Value.ToLower() == "food1"
                            select new Categories
                            {
                                Title = cats.Element("Title").Value,
                                Cat = cats.Element("Cat").Value,
                                Duration = cats.Element("Duration").Value,
                                Description = cats.Element("Description").Value
                            }).ToList();

You can then bind the list...

Place holder class for Categories Type

internal class Categories
    {
        public string Title { get; set; }
        public string Cat { get; set; }
        public string Duration { get; set; }
        public string Description { get; set; }
    }
RandomNoob
A: 

Why don't you just set up a series of if statements to see what arguments where passed in the query string, and then generate the appropriate XPath expression accordingly?

Something like:

string xpath = "/Categories/Category";
string predicate = "";

if (_food != "") {
    predicate += "title='" + _food + "'";
}
if (_Cat != "") {
    if (predicate!="") {
        predicate += " and ";
    }
    predicate += "Cat='" + _Cat + "'";
}
if (_Description != "") {
    if (predicate!="") {
        predicate += " and ";
    }
    predicate += "Description='" + _Description + "'";
}

if (predicate!=""){
    xpath += "[" + predicate + "]";
}
XPathExpression expression = nav.Compile(xpath);
Roland Bouman
I would like to add that f you use this solution, you must process the values passed in the query string to prevent xpath injection.
Roland Bouman
Thanks Roland its working fine....
AB