28

This query seems to be valid, but I have 0 results.

IEnumerable<XElement> users =
            (from el in XMLDoc.Elements("Users")
             where (string)el.Attribute("GUID") == userGUID.ToString()
             select el);

My XML is as follows:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Users>
  <User GUID="68327fe2-d6f0-403b-a7b6-51860fbf0b2f">
    <Key ID="F7000012ECEAD101">
      ...
    </Key>
  </User>

</Users>

Do you have any clues to shed some light onto this?

Patrick Karcher
  • 22,995
  • 5
  • 52
  • 66
Ignacio
  • 7,947
  • 15
  • 63
  • 74

2 Answers2

54

Well, the Users elements don't have GUID attributes. Two suggested options:

  • Look at XDocument.Root.Elements("User")
  • Use Descendants("User") to find all User elements.

I'll stick with the former for the moment. That gives us:

IEnumerable<XElement> users =
            (from el in XMLDoc.Root.Elements("User")
             where (string) el.Attribute("GUID") == userGUID.ToString()
             select el);

Now, we can still tidy this up further. Firstly, let's cast to Guid instead of string:

IEnumerable<XElement> users =
    (from el in XMLDoc.Root.Elements("User")
     where (Guid) el.Attribute("GUID") == userGUID
     select el);

However there's not a lot of reason to use a query expression here... all you're applying is a single predicate. Let's just use the Where method directly:

IEnumerable<XElement> users = 
    XMLDoc.Root
          .Elements("User")
          .Where(el => (Guid) el.Attribute("GUID") == userGUID);

How you lay it out is up to you, of course :) With a longer line, you can probably align everything up under a longer first line:

IEnumerable<XElement> users = XMLDoc.Root
                                    . etc

Now, finally - what about if the User element doesn't have a GUID attribute? Currently, this code will throw an exception. That may be exactly what you want - or it may not. If it's not, you can make it ignore such things by casting to Nullable<Guid> aka Guid? instead:

IEnumerable<XElement> users = 
    XMLDoc.Root
          .Elements("User")
          .Where(el => (Guid?) el.Attribute("GUID") == userGUID);
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
38

change Users in the 2nd line to User. Like this:

    IEnumerable<XElement> users = (from el in XMLDoc.Root.Elements("User")
                                   where (string)el.Attribute("GUID") ==  userGUID.ToString()
                                   select el);

I'm assuming XMLDoc is an XDocument, and not the root element itself.

FoldFence
  • 2,674
  • 4
  • 33
  • 57
Patrick Karcher
  • 22,995
  • 5
  • 52
  • 66
  • 1
    Thanks, this was partly what I needed, a stupid mistake from me. – Ignacio Apr 20 '10 at 20:34
  • 3
    As Jon points out below, casting to the correct type is a better choice. Additionally, if you use "el.Attribute("GUID").Value" you automatically get a string as the return type and there is no need for the cast. – Dan Bailiff Apr 11 '11 at 21:08
  • 2
    `root` should be `Root` in `XMLDoc.root.Elements("User")`. – Appulus Aug 21 '13 at 09:37
  • I know this is an older post, but shouldn't it be 'where el.Attribute("GUID").Value == userGUID.ToString()' assuming that the userGUID is a GUID? – Levi Fuller Mar 16 '15 at 23:30
  • How would I achieve the same with a Sharepoint `_api` feed? I would like to get multiple child elements from each parent elements? – Si8 Mar 20 '17 at 14:01