tags:

views:

119

answers:

3

I'm trying to add all the nodes in an XML file into a listView, and I'm doing something wrong but I can't for the life of me figure it out even after looking at a load of examples. This is the XML snippet:

<queue>
<slots>
<slot>
<status>Downloading</status>
<filename>file1</filename>
<size>1 GB</size>
</slot>
<slot>
<status>Downloading</status>
<filename>file2</filename>
<size>2 GB</size>
</slot>
</slots>
</queue>

And here's the code:

        XDocument xDoc = XDocument.Load(xmlFilePath);

        List<Download> list = new List<Download>();

        foreach (var download in xDoc.Descendants("slots"))
        {
            string filename = download.Element("filename").Value;
            string size = download.Element("size").Value;
            string status = download.Element("status").Value;
            list.Add(new Download { Filename = filename, Size = size, Status = status });              
        }

Any help greatly appreciated as always.

EDIT: To clarify, I'm getting a NullReferenceException on

string filename = download.Element("filename").Value;

And i know the listview is missing, I've not done that bit yet :)

+3  A: 
var list = (from download in xDoc.Descendats("slot")
            select new Download
                    {
                        Filename = (string) download.Element("filename"),
                        Size = (string) download.Element("size"),
                        Status = (string) download.Element("status")
                    }).ToList();

This looks nicer, and since you didn't say what exactly is wrong with your code, it's about all I can do.

Update: just tested this, and it fixes your exception.

Necros
Spot on, and it does look nicer too!
JoeBeez
This fixes the NullReferenceException by ignoring the possibly malformed XML and inserting a null for the filename.
Yuriy Faktorovich
@Yuriy The `NullReferenceException` was caused by trying to access `filename` node as an element of `slots` node, instead of an element of `slot` node. You can take care missing values later (e.g. `.Where(d => !string.IsNullOrEmpty(d.Filename))`).
Necros
Sure if he changed it, but originally he had `slot`.
Yuriy Faktorovich
+2  A: 

The XML in your example works fine. The NullReferenceException is happening because the real XML you're using doesn't have a filename element in one of the slots. You can use

string filename = download.Element("filename") == null ? 
    String.Empty : download.Element("filename").Value;

instead if there is a possible default for the filename. But more likely correctly handling this exception is better.

Yuriy Faktorovich
+1 for finding his bug!
JohnB
+1  A: 
void LoadSlots()
{
  XmlDocument doc = new XmlDocument();
  doc.Load(Environment.CurrentDirectory + "\\queue.xml");

  XmlNodeList nodes = doc.SelectNodes("//queue/slots/slot");

  foreach (XmlNode node in nodes)
  {
    string filename = node.Attributes["filename"].InnerText;
    string size = node.Attributes["size"].InnerText;
    string status = node.Attributes["status"].InnerText;
    _slots.Add(filename, size, status);
  }
}
JohnB
Why did you change it to use XmlDocument instead of XDocument? Then you have filename, size and status as attributes instead of elements as originally posted. And then there is a cryptic _slots, what is it?
Yuriy Faktorovich
Sorry, I ran it and it works though. Replace `_slots` with `list`. I just gave it a specific name, i.e. `private List<QueueSlot> _slots = new List<QueueSlot>();`
JohnB
Another typo though, should be, `_slots.Add(new QueueSlot(filename, size, status);`
JohnB
I did it the old fashioned way! It's probably inefficient or something though.
JohnB