0

I am trying to create a function to parse an XML file like this:

<?xml version="1.0" encoding="utf-8"?>
<list name="Grocery List" author="Ian" desc="Saturday grocery list">

        <item color="black" done="false">Milk</item>
        <item color="black" done="false">Eggs</item>
        <item color="blue" done="false">Water</item>

</list>

It parses the attributes correctly, but it fails to return the values of the list items. Here is the function and class it uses:

class List
{
    public string[] listItems;
    public string[] colorArray;
    public string[] doneArray;
    public string listName;
    public string listAuthor;
    public string listDesc;
    public string err;       
}

Reader definition:

class ListReader
{
    public List doListParse(string filename)
    {
         List l = new List();

         int arrayCount = 0;

         try
         {
             XmlReader r = XmlReader.Create(filename);

             while (r.Read())
             {
                 if (r.NodeType == XmlNodeType.Element && r.Name == "list")
                 {
                     //Get the attributes of the list
                     l.listName = r.GetAttribute("name");
                     l.listAuthor = r.GetAttribute("author");
                     l.listDesc = r.GetAttribute("desc");

                     while (r.NodeType != XmlNodeType.EndElement)
                     {
                         r.Read();
                         if (r.Name == "item")
                         {
                             r.Read();
                             if (r.NodeType == XmlNodeType.Text)
                             {
                                 //Get The Attributes
                                 l.colorArray[arrayCount] = r.GetAttribute("color");
                                 l.doneArray[arrayCount] = r.GetAttribute("done");

                                 //Get The Content
                                 l.listItems[arrayCount] = r.Value.ToString();

                                 arrayCount++;
                             }
                             r.Read();
                         }
                     }
                 }
             }
         }
         catch (Exception e)
         {
             l.err = e.ToString();
         }

         return l;
    }
}

When I execute the program, it gives this exception:

System.NullReferenceException: Object reference not set to an instance of an object.

What is going on here?

2
  • 4
    try { while { if { while { if { if { ...bugs prosper here... } } } } } } } Commented Feb 9, 2013 at 15:27
  • 2
    You never init the 3 arrays in your class. Commented Feb 9, 2013 at 15:29

2 Answers 2

5

I'd recommend you using a serializer. The XmlSerializer class is pretty decent. It will simplify your code.

So start by defining the models that will map to this XML structure:

[XmlRoot("list")]
public class GroceryList
{
    [XmlAttribute("name")]
    public string Name { get; set; }

    [XmlAttribute("author")]
    public string Author { get; set; }

    [XmlAttribute("desc")]
    public string Description { get; set; }

    [XmlElement("item")]
    public Item[] Items { get; set; }
}

public class Item
{
    [XmlAttribute("color")]
    public string Color { get; set; }

    [XmlAttribute("done")]
    public bool Done { get; set; }

    [XmlText]
    public string Value { get; set; }
}

and then simply deserialize the XML:

class Program
{
    static void Main()
    {
        var serializer = new XmlSerializer(typeof(GroceryList));
        using (var reader = XmlReader.Create("groceriesList.xml"))
        {
            var list = (GroceryList)serializer.Deserialize(reader);
            // you could access the list items here
        }
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

I'll try that. It certainly looks quite a lot nicer than my mess of code. :)
0

You can use Linq To Xml.

var xElem = XDocument.Parse(xml).Element("list"); //or XDocument.Load(filename)
var list = new
            {
                Name = xElem.Attribute("name").Value,
                Author = xElem.Attribute("author").Value,
                Desc = xElem.Attribute("desc").Value,
                Items = xElem.Elements("item")
                            .Select(e => new{
                                Color = e.Attribute("color").Value,
                                Done = (bool)e.Attribute("done"),
                                Value = e.Value,
                            })
                            .ToList()
            };

Comments

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.