Kiwimoisi
Kiwimoisi

Reputation: 4182

Read XML Attribute

I am actually trying to read this piece of XML.

http://datapoint.metoffice.gov.uk/public/data/val/wxfcs/all/xml/351352?res=3hourly&key=99b9f578-ad3d-446c-9d29-0bbee028b483

I was wondering how I could read only the node Period with the value="2012-11-15Z"

So the one below :

This is the code I use

 using (XmlReader reader = XmlReader.Create("http://datapoint.metoffice.gov.uk/public/data/val/wxfcs/all/xml/351352?res=3hourly&key=99b9f578-ad3d-446c-9d29-0bbee028b483"))
    {
        reader.MoveToContent();
        while (reader.Read())
        {
            if (reader.NodeType == XmlNodeType.Element
                && reader.Name == "Period")
            {
                while (reader.Read())
                {
                    if (reader.NodeType == XmlNodeType.Element &&
                        reader.Name == "Rep")
                    {
                        first.Text = reader.GetAttribute("T");
                    }
                }


            }
        }
    }

What is the way for me to read only this node ?

Should I write

if (reader.NodeType == XmlNodeType.Element && reader.Name == "Period" && reader.GetAttribute("value") == "2012-11-15Z")

This doesn't seem to work ..

Can someone help me ?

Upvotes: 0

Views: 259

Answers (2)

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236218

You can easily do that with LINQ to XML:

XDocument xdoc = XDocument.Load(path_to_xml);
var period = xdoc.Descendants("Period")
                 .Where(p => (string)p.Attribute("value") == "2012-11-15Z") 
                 .SingleOrDefault();

It will return XElement, but you can select any data from period. E.g. T attributes:

List<int> tList = xdoc.Descendants("Period")
                      .Where(p => (string)p.Attribute("value") == "2012-11-15Z")
                      .SelectMany(p => p.Elements())
                      .Select(rep => (int)rep.Attribute("T"))
                      .ToList();

var query = xdoc.Descendants("Period")
                .Where(p => (string)p.Attribute("value") == "2012-11-15Z")
                .SelectMany(p => p.Elements())
                .Select(rep => new { 
                      T = (int)rep.Attribute("T"),
                      D = (string)rep.Attribute("D") })
                .ToList();

Last query will return List of strongly-typed anonymous objects with integer property T and string property D:

 foreach(var x in query)
     // use x.T and x.D

Upvotes: 2

Kami
Kami

Reputation: 19407

Try using xpath to lookup the value like this

XmlDocument doc = new XmlDocument();
using (XmlReader reader = XmlReader.Create("http://datapoint.metoffice.gov.uk/public/data/val/wxfcs/all/xml/351352?res=3hourly&key=99b9f578-ad3d-446c-9d29-0bbee028b483"))
{
    doc.Load(reader);
    XmlNodeList list = doc.SelectNodes("//Period[@value='2012-11-15Z']");
    Console.WriteLine(list.Count);
}

Upvotes: 0

Related Questions