Hello there.

My aim is to use the Flickr API to extract details of only one photograph given a set of keywords.

I have the request URL which (in a browser) returns XML much like the following:

<rsp stat="ok">
<photos page="1" pages="8951" perpage="100" total="895061">
<photo id="4503248539" owner="33965274@N08" secret="b60e5fcc27" server="2774" farm="3" title="alright, tia" ispublic="1" isfriend="0" isfamily="0"/>
<photo id="4503259303" owner="49065542@N00" secret="1765234706" server="4053" farm="5" title="French Bulldog" ispublic="1" isfriend="0" isfamily="0"/>
<photo id="4503856822" owner="33703729@N08" secret="36e52001bc" server="2784" farm="3" title="Lucky" ispublic="1" isfriend="0" isfamily="0"/>
<photo id="4503856622" owner="33703729@N08" secret="749f915a37" server="4041" farm="5" title="Mini" ispublic="1" isfriend="0" isfamily="0"/>
</photos>
</rsp>

All I'd like, in the example above, is to extract each of the attributes from the very first <photo> element.

How would I load the XML within C# and extract the attributes neatly?

Thank you very much!

You can use LINQ to XML (System.Xml.Linq namespace) to parse the XML file.

string xml = 
@"<rsp stat=""ok"">
<photos page=""1"" pages=""8951"" perpage=""100"" total=""895061"">
<photo id=""4503248539"" owner=""33965274@N08"" secret=""b60e5fcc27"" server=""2774"" farm=""3"" title=""alright, tia"" ispublic=""1"" isfriend=""0"" isfamily=""0""/>
<photo id=""4503259303"" owner=""49065542@N00"" secret=""1765234706"" server=""4053"" farm=""5"" title=""French Bulldog"" ispublic=""1"" isfriend=""0"" isfamily=""0""/>
<photo id=""4503856822"" owner=""33703729@N08"" secret=""36e52001bc"" server=""2784"" farm=""3"" title=""Lucky"" ispublic=""1"" isfriend=""0"" isfamily=""0""/>
<photo id=""4503856622"" owner=""33703729@N08"" secret=""749f915a37"" server=""4041"" farm=""5"" title=""Mini"" ispublic=""1"" isfriend=""0"" isfamily=""0""/>
</photos>
</rsp>";

XDocument document = XDocument.Parse(xml);

var photos = from photo in document.Descendants("photo")
             select new
             {
                 Id = photo.Attribute("id").Value,
                 Owner = photo.Attribute("owner").Value,
                 Secret = photo.Attribute("secret").Value,
                 Server = photo.Attribute("server").Value,
                 Farm = (int)photo.Attribute("farm"),
                 Title = photo.Attribute("title").Value,
                 IsPublic = (photo.Attribute("ispublic").Value == "1"),
                 IsFriend = (photo.Attribute("isfriend").Value == "1"),
                 IsFamily = (photo.Attribute("isfamily").Value == "1")
             };

var firstPhoto = photos.First();

This piece of code will load an XML string into an XDocument and then project each photo element into an anonymous type. Notice the syntax of turning the "farm" attribute into an int as well as the "is___" attributes into bools based on their values equaling 1.

Finally, to get just the first photo, all that needs to be done is to use the .First() extension method on the original query.

You can use LINQ to XML (System.Xml.Linq namespace) to parse the XML file.

Perfect, thank you; I've actually used LINQ to XML before but never thought to try that.

In your example above, how would I load the XML document from a remote (online) URL into a C# string or object? I've only done that with the XMLDocument (and the .Load method).

Thanks again!

using System;
using System.IO;
using System.Net;
using System.Text;


string remoteURL ="http://cdn.forexfactory.com/ffcal_week_this.xml";

        private string getHTTP(string szURL)
        {
            HttpWebRequest httpRequest = null;
            HttpWebResponse httpResponse = null;
            string bodyText = "";
            Stream responseStream = null;
            Byte[] RecvBytes = new byte[byte.MaxValue];
            Int32 bytes;
            try
            {
                httpRequest = (HttpWebRequest)WebRequest.Create(szURL);
                httpResponse = (HttpWebResponse)httpRequest.GetResponse();
                responseStream = httpResponse.GetResponseStream();
                while (true)
                {
                    bytes = responseStream.Read(RecvBytes, 0, RecvBytes.Length);
                    if (bytes <= 0) break;
                    bodyText += System.Text.Encoding.UTF8.GetString(RecvBytes, 0, bytes);
                }
            }
            catch (Exception e)
            {
                bodyText = "HTTP Error:" + e.Message;
            }
            finally
            {
                httpRequest = null;
                httpResponse = null;
                if (responseStream != null)
                {
                    responseStream.Dispose();
                    responseStream = null;
                }
            }
            return bodyText;
        }

string xml = getHTTP(remoteURL)

Edited 3 Years Ago by pyTony: fixed formatting

This article has been dead for over six months. Start a new discussion instead.