Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Select nodes Linq to Xml C#

XML file format:

<?xml version="1.0" encoding="UTF-8"?>
    <urlset>    
        <url>
            <loc>element1</loc>
            <changefreq>daily</changefreq>
            <priority>0.2</priority>
        </url>
        <url>
            <loc>element2</loc>
            <changefreq>daily</changefreq>
            <priority>0.2</priority>
        </url>
    <urlset>

I want to select all "loc" nodes (element1, element2), but this not work!!!

 foreach (XElement item in document.Elements("url").Descendants("loc")) // Change into what?
 {
      urlList.Add(item.Value);
 }
like image 845
Chelsea_cole Avatar asked Aug 06 '11 09:08

Chelsea_cole


2 Answers

I suspect the problem is that you're going from document.Elements("url") instead of document.Root.Elements("url")... so it's looking for a root element of url, which doesn't exist.

Try this:

List<string> urlList = doc.Root.Elements("url")
                               .Elements("loc")
                               .Select(x => (string) x)
                               .ToList();

Note that I haven't used Descendants here, as the loc elements are all directly beneath url elements anyway.

Another alternative you could use if the only loc elements are the right ones anyway, is just:

List<string> urlList = doc.Descendants("loc")
                          .Select(x => (string) x)
                          .ToList();

(I'm assuming urlList was empty beforehand... for this sort of situation I like to use LINQ for the whole operation and eliminate foreach loops that are just adding to a collection.)

EDIT: The code works for me. Here's a short but complete program:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

class Test
{
    static void Main(string[] args)
    {
        string xml = @"<?xml version=""1.0"" encoding=""UTF-8""?>
    <urlset>    
        <url>
            <loc>element1</loc>
            <changefreq>daily</changefreq>
            <priority>0.2</priority>
        </url>
        <url>
            <loc>element2</loc>
            <changefreq>daily</changefreq>
            <priority>0.2</priority>
        </url>
    </urlset>";

        XDocument doc = XDocument.Parse(xml);
        List<string> urlList = doc.Root
                                  .Elements("url")
                                  .Elements("loc")
                                  .Select(x => (string) x)
                                  .ToList();
        Console.WriteLine(urlList.Count);
    }
}
like image 127
Jon Skeet Avatar answered Oct 22 '22 14:10

Jon Skeet


var xDoc = XDocument.Parse(
    @"<urlset>    
        <url>
            <loc>element1</loc>
            <changefreq>daily</changefreq>
            <priority>0.2</priority>
        </url>
        <url>
            <loc>element2</loc>
            <changefreq>daily</changefreq>
            <priority>0.2</priority>
        </url>
    </urlset>");
var locElements = xDoc.Descendants("url").SelectMany(el => el.Descendants("loc"));
like image 22
VMAtm Avatar answered Oct 22 '22 16:10

VMAtm