views:

299

answers:

6

I was wondering if there is a way to get a list of results into a list with linq to xml. If I would have the following xml for example:

<?xml version="1.0"?>
<Sports xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
    <SportPages>
        <SportPage type="test">
            <LinkPage>
                <IDList>
                    <string>1</string>
                    <string>2</string>
                </IDList>
            </LinkPage>
        </SportPage>
    </SportPages>
</Sports>

How could I get a list of strings from the IDList?

I'm fairly new to linq to xml so I just tried some stuff out, I'm currently at this point:

var IDs = from sportpage in xDoc.Descendants("SportPages").Descendants("SportPage")
                      where sportpage.Attribute("type").Value == "Karate"
                      select new
                      {
                          ID = sportpage.Element("LinkPage").Element("IDList").Elements("string")
                      };

But the var is to chaotic to read decently. Isn't there a way I could just get a list of strings from this?

Thanks

+2  A: 
var myStrings = xDoc.Descendants("SportPage")
                    .Where(d => d.Attribute("type").Value == "Karate")
                    .Descendants("IDList")
                    .Descendants("string")
                    .Select(d => d.Value);

to see your string:

xDoc.Descendants("SportPage")
    .Descendants("IDList")
    .Where(d => d.Attribute("type").Value == "Karate")
    .Descendants("string")
    .Select(d => d.Value)
    .ToList()
    .ForEach(Console.WriteLine);
Yuriy Faktorovich
but you're neglecting the condition `sportpage.Attribute("type").Value == "Karate"`
marc_s
A: 

You don't need linq to XML to do this. Use System.Xml.Serialization.

http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx

http://devhood.com/Tutorials/tutorial_details.aspx?tutorial_id=236

Matt Ball
-1: he doesn't want the whole object, he wants a list of the ids.
John Saunders
That sounded like just an example to me, but ok. I was thinking more generally.
Matt Ball
+1  A: 

Do you mean this?

List<string> IDs = xDoc.Descendants("SportPages").Descendants("SportPage")
    .Where( anySportPage => anySportpage.Attribute("type").Value == "Karate" )
    .Select( karateSportPage => karateSportpage.Element("LinkPage").Element("IDList").Elements("string"))
    .ToList();
ANeves
I'm getting: "Error: Cannot implicitly convert type 'System.Collections.Generic.List<System.Collections.Generic.IEnumerable<System.Xml.Linq.XElement>>' to 'System.Collections.Generic.List<string>'"
marc_s
Also you need to be more careful with your upper- and lower-case: e.g. this statement doesn't work: `.Where( anySportPage => anySportpage. ` - you need to use the same casing in both cases!! `anySportPage vs. anySportpage` - not identical!
marc_s
Born out of not testing and assuming I knew what came out of the `.Elements()`. (Using `var IDs` would work, but I never really liked `var`.) Thanks for the corrections, and for writing down a correct answer. :)
ANeves
A: 

I think the reason you find the "var" chaotic is your creation of the anonymous type with the "new" in your select. If you just select the one item you're after then the var will not be an anonymous type.

e.g.

select sportpage.Element("LinkPage").Element("IDList").Elements("string");

However, my preference would be to do that using the . notation like this.

List<string> ids = xDoc.Elements("SportPages").Elements("SportPage").Where(sportPage => sportPage.Attribute("type").Value == "Karate").Elements("LinkPage").Elements("IDList").Elements("string").Select(id => id.Value).ToList();
Robin Day
+2  A: 

This query works - tested and verified:

var ID2 = (from sportpage in xDoc.Descendants("SportPages").Descendants("SportPage")
           where sportpage.Attribute("type").Value == "Karate"
           select sportpage)
          .Descendants("LinkPage")
          .Descendants("IDList")
          .Elements("string")
          .Select(d => d.Value)
          .ToList();

Gives me a list of two strings, "1" and "2".

marc_s
This will throw a object null exception if you ever have a `SportPage` element that doesn't have a `type` attribute.
Matthew Whited
solved it, I removed the LinkPage descendants and SportPages descendants because thanks to other replies I figured out it autosearches :) So thanks a lot all of u!
WtFudgE
A: 

The biggest issue you were having was that you didn't grab the .Value from the returned element set. But here's another way to do it.

var ids = from sportPage in xDoc.Descendants("SportPage")
          let attrib = sportPage.Attribute("type")
          where attrib != null
          let type = attrib.Value
          where !string.IsNullOrEmpty(type)
              && type == "Karate"
          from id in sportPage.Descendants("IDList").Elements()
          select id.Value;
Matthew Whited
This way is rather lazy. If you have an explicit schema you can use the same thing you have in your example in the question. You just need to add a `.Value` to the end of the statement in your select.
Matthew Whited