Search code examples
c#xmllinqxml-deserialization

C# deserialize xml using linq


I have the following xml file

<?xml version="1.0" encoding="utf-8"?>
<Launchpad>
  <Shortcuts>
    <Shortcut Id="1">
      <Type>Folder</Type>
       <FullPath>C:\bla\bla\bla</FullPath>
       <Name>Proximity</Name>
    </Shortcut>
    <Shortcut Id="2">
      <Type>Folder</Type>
      <FullPath>C:\bla</FullPath>
      <Name>Visual Studio 2017</Name>
    </Shortcut>
  </Shortcuts>
</Launchpad>

I am trying to deserialize to an object like this: (Tried query syntax first, didn't work either)

XDocument xd = XDocument.Load(FullPath);

// query syntax
//var shortcuts = (from s in xd.Descendants("Shortcuts")
//                 select new Shortcut()
//                 {
//                   Id = Convert.ToInt32(s.Attribute("Id")),
//                   TypeOfLink = GetTypeFromString(s.Descendants("Type") 
//                                .First()
//                                .Value),
//                   FullPathToTarget = s.Descendants("FullPath") 
//                                         .First()
//                                         .Value,
//                   Name = s.Descendants("Name").First().Value,
//                 }).ToList();

// method syntax
List<Shortcut> shortcuts = xd.Descendants("Shortcuts")
                             .Select(s => 
               new Shortcut()
               {
                 //Id = Convert.ToInt32(s.Attribute("Id")),
                 TypeOfLink = GetTypeFromString(s.Descendants("Type") 
                                                 .First().Value),
                 FullPathToTarget = s.Descendants("FullPath")
                                                 .First().Value,
                 Name = s.Descendants("Name")
                         .First().Value,
               }).ToList();
return shortcuts;

For some reason I only get a single shortcut object in the list. Also, for some reason, the s.Attribute("Id") is null.

If anyone has any suggestions to improve the linq query or why the attribute is not working it would be a great help


Solution

  • I get the full list by selecting the Shortcut as a descendant of Shortcuts.

    Also, ID is an XAttribute so you cant convert it to int.

    You need to use Value to get the attributes value.

    XDocument xd = XDocument.Load(ms);
    XElement root = xd.Document.Root;
    var list = root.Descendants("Shortcuts").Descendants("Shortcut").Select(x =>
        new Shortcut()
        {
            Id = Convert.ToInt32(x.Attribute("Id").Value),
            TypeOfLink = GetTypeFromString(x.Descendants("Type")
                                            .First().Value),
            FullPathToTarget = x.Descendants("FullPath")
                                            .First().Value,
            Name = x.Descendants("Name").First().Value
            }).ToList();