XML XDocument There appears to be no elements

I'm trying to understand XDocument and it's various methods.

I have a site map, and I'm trying to read the URLs

<urlset xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
    <url>
         <loc>http://www.site.co.uk/</loc>
    </url>
    <url>
         <loc>http://www.site.co.uk/page</loc>
    </url>
</urlset>

The above parses fine and I'm trying to read the values of loc (the page URLs) but this where it goes wrong

        string siteMapText = String.Empty();
        GetValueOfPageFromWebClient(SiteMapUrl, out siteMapText);

        XDocument siteMap =
            XDocument.Parse(siteMapText);

        foreach (var loc in siteMap.Descendants())
        {
            //logic
        }

In my C#

loc.Element("loc").Value //should show value but doesn't

How do I iterate over the loc values?

EDIT

As per Jon Skeet's answer, I tried

If I do

  foreach (var loc in siteMap.Descendants("loc"))
  {
      //never enters
  }

The same is true with

  foreach (var loc in siteMap.Descendants("url"))
  {
      //never enters
  }

I've had to do foreach (var loc in siteMap.Descendants()) { if (loc.Name.LocalName != "url") continue; //code }

Can some one explain why this is the case?

Jon Skeet
people
quotationmark

How do I iterate over the loc values?

The simplest way is to use the overload of Descendants which accepts an XName:

foreach (var loc in siteMap.Descendants("loc"))
{
    string value = loc.Value;
    ...
}

Currently, you're asking for the loc element within each element - but neither the root element nor the loc elements contain loc child elements, so Element returns null, leading to an exception.

Now it seems that the XML isn't actually as you've shown it to be in the question. Instead, it has a default namespace:

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" ...>

So all the descendant elements are in that namespace too, because they don't specify anything else... so you need to specify the namespace when you're looking for things. Fortunately, that's easy:

XNamespace ns = "http://www.sitemaps.org/schemas/sitemap/0.9";
foreach (var loc in siteMap.Descendants(ns + "loc"))
{
    ...
}

people

See more on this question at Stackoverflow