views:

70

answers:

3

I have a relatively small xml file

<g>
  <page no="1" href="page1.xml" >        
      <pic src="20100101001.jpg">1</pic>
      <pic src="20100101002.jpg">2</pic>
      <pic src="20100101003.jpg">3</pic>           
  </page>
  <page no="2" href="page2.xml" >        
      <pic src="20100101011.jpg">1</pic>
      <pic src="20100101012.jpg">2</pic>
      <pic src="20100101013.jpg">3</pic>            
  </page>
  <page no="3" href="page3.xml" >       
      <pic src="20100101021.jpg">1</pic>
      <pic src="20100101022.jpg">2</pic>
      <pic src="20100101023.jpg">3</pic>            
  </page>  
</g>

I want to have three buttons (page1,page 2,page 3) on a win form that when clicked they load the relevant 3 pictures in three pictures box(the three pictures are under the same page in the xml file).

I need something that does something like "select from xml where page = X"

I know that I can do this using xpath(/other xml objects) or a treeview object... but I don't know much about any of those object, and I certainly can't tell the pros and cons of each...

So I need your help :) Thanks Asaf

+1  A: 

I suggest you to use LINQ to XML

Sample Code from: link

XDocument loaded = XDocument.Load(@"C:\contacts.xml");


// Query the data and write out a subset of contacts
var q = from c in loaded.Descendants("contact")
    where (int)c.Attribute("contactId") < 4
    select (string)c.Element("firstName") + “ “ +
       (string)c.Element("lastName");


foreach (string name in q)
   Console.WriteLine("Customer name = {0}", name);
mehmet6parmak
+2  A: 

As @mehmet6parmak writes in his answer, I would suggest using LINQ to XML. And here's the code for your XML data:

using System.Xml.Linq;

XDocument doc = XDocument.Load(@"C:\Path\To\XmlFile");

int pageNo = 1;
var page = e.Descendants("page").FirstOrDefault(x => x.Attribute("no").Value == pageNo.ToString());

If you have Page and Picture classes like these

public class Page
{
    public int No {get;set;}
    public string Href {get;set;}
    public IList<Picture> Pictures {get;set;}
}
public class Picture
{
    public string Source {get;set;}
}

you can generate them from XML as follows:

using System.Xml.Linq;

var xPage = e.Descendants("page").FirstOrDefault(x => x.Attribute("no").Value == "1");
var page = new Page
{
    No = Convert.ToInt32(xPage.Attribute("no").Value),
    Href = xPage.Attribute("href").Value
};
page.Pictures = xPage.Descendants("pic").Select(x => new Picture { Source = x.Attribute("src").Value }).ToList();
Dave
+2  A: 

Here is a solution involving XPathDocument and XPath. This is more light-weight regarding memory than using Linq (XDocument) or XmlDocument because it doesn't build up a DOM in memory. For small files this usually does not matter but XPathDocument will be much faster on large input.

string page = "page1.xml";
XPathDocument xdoc = new XPathDocument(@"C:\tmp\smpl6.xml");

XPathNodeIterator result = xdoc.CreateNavigator()
    .Select(string.Format("/g/page[@href = '{0}']/pic/@src", page));

foreach (XPathNavigator item in result)
{
    Trace.WriteLine(item.Value);
}

You can change that XPath expression easily, e.g. to filter by the page number:

int pageNo = 2;
XPathNodeIterator result = xdoc.CreateNavigator()
    .Select(string.Format("/g/page[@no = '{0}']/pic/@src", pageNo));    
0xA3
Just out of curiosity, is there an advantage to use XPath over LINQ to XML?
Dave
XPathDocument builds a complete object model in memory. It is not a W3C DOM model and it is not a LINQ to XML model, instead it is a tree model for XPath and XSLT, but nevertheless it is a tree model of the complete XML document. It might be slightly lighter than DOM or LINQ to XML as it is a read only model while those two allow manipulations in addition to querying.
Martin Honnen