4

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">
    <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

5 Answers 5

6

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".

Sign up to request clarification or add additional context in comments.

2 Comments

This will throw a object null exception if you ever have a SportPage element that doesn't have a type attribute.
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!
2
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);

1 Comment

but you're neglecting the condition sportpage.Attribute("type").Value == "Karate"
1

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();

3 Comments

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>'"
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!
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. :)
0

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();

Comments

0

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;

1 Comment

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.