1

I've searched but couldn't find anything similar as this is probably very basic. I'm basically trying to read a list of movies from an xml file and then to pass it back into a Model for various types of consumption. But I get a "System.NullReferenceException: Object reference not set to an instance of an object." My (sudo) c# code looks something like this

        var xmlDoc = new XmlDocument();
        xmlDoc.Load("c:\\movies.xml");
        var movieModel = new MovieSummary();
        var MovieXML = xmlDoc.GetElementsByTagName("movie");
        int i;

        for (i = 0; i < MovieXML.Count; i++)
        {
            movieModel.Movies[i].name = MovieXML[i]["name"].toString();
        }

my Model looks like this

 namespace movies.Models
 {

     public class MovieSummary
     {
         public List<Movie> Movies { get; set; }
     }

     public class Movie
     {
         public string movie { get; set; }
     }
 }

xml file looks like

 <movies xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
      <movie>
       <name>The Dark Knight</name>
  </movie>
  <movie>
       <name>Iron Man</name>
  </movie>
 </movies>
totalnoob
  • 2,521
  • 8
  • 35
  • 69

2 Answers2

2

I think you are better off with using XmlSerializer if the structure of your xml file is resembled in your classes by inheritance.

Write a function which Deserialize your xml to your classes.

public static MovieSummary Deserialize()
{
    XmlSerializer serializer = new XmlSerializer(typeof(MovieSummary));
    TextReader textReader;

    textReader = new StreamReader(pathtoyourxmlfile);

    MovieSummary summary = (MovieSummary)serializer.Deserialize(textReader); 
    textReader.Close();
    return summary;
}

Hope that helps

Amila
  • 3,711
  • 3
  • 26
  • 42
1

If you are ONLY going to ever be loading a list of movies from an xml file, and that't it, you should check out the following link on MSDN: http://msdn.microsoft.com/en-us/library/system.xml.xmldocument.getelementsbytagname%28v=vs.71%29.aspx

This would be a solution for that approach:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var xmlDoc = new XmlDocument();
            xmlDoc.Load("c:\\movies.xml");
            var movieModel = new MovieSummary();
            var MovieXML = xmlDoc.GetElementsByTagName("movie");
            movieModel.Movies = new List<Movie>();
            foreach (XmlElement element in MovieXML)
            {
                movieModel.Movies.Add(new Movie(){movie = element.InnerText});                
            }
            //for (i = 0; i < MovieXML.Count; i++)
            //{
            //    movieModel.Movies[i].name = MovieXML[i]["name"].toString();
            //}
        }
    }
}

If you are going to plan on loading anything more than just movies from the xml file or you think you'll ever need more flexibility in loading multiple nodes from multiple xml files, I'd advise using the xmlserialization ability of .NET via the xsd.exe tool. Do your xml files adhere to a common xsd schema. If they dont, dont worry, you can create a common schema for your xml files using xsd.exe (its part of visual studio). Once you have generated the xsd file from your sample xml file, you can use that xsd file to generate classes using that same xsd.exe tool.

Once that is done, you can add the generated class or classes to your model as members, wrap them as you see fit, and bulk load the data from the xml file into the member classes with a few lines of code. And that will work for any xml file so long as it adheres to said xsd file. You an also load and unload the data to and from xml file to and from classes using serializer classes.

There are many ways to do what you are talking about, and I've tried many ways. However, this by far the best way to do things because it allows you to load as many different xml files as you want without having to rewrite the methods that load the xml (Again, as long as what you're loading adheres to the xsd file).

http://msdn.microsoft.com/en-us/library/x6c1kb0s%28v=vs.71%29.aspx

  • nothing too crazy, just need to load items from one file, and just the movies for now. – totalnoob Jul 04 '13 at 17:16
  • from the first link, I've changed my code to XmlNodeList MovieXML = xmlDoc.GetElementsByTagName("movie"); and for (int i = 0; i < MovieXML.Count; i++) { movieModel.Movies[i].name = MovieXML[i].InnerXml.ToString(); } same issue – totalnoob Jul 04 '13 at 17:20
  • Let me know if the above doesn't work for you. If it does, an upvote and correct answer would be greatly appreciated!! –  Jul 04 '13 at 18:00
  • I tested what I posted above. It works exactly as you described. –  Jul 05 '13 at 00:06
  • this works nicely, one additional question. if I had one other thing in the class, let's say public int id { get; set; } and the xml file had 1, how would I also add the id with movieModel.Movies.Add(new Movie(){movie = element.InnerText}); – totalnoob Jul 05 '13 at 14:16
  • you'd write something like movieModel.Movies.Add(new Movie(){movie = element.InnerText, id = element.id}; Note:you might need to search for id a bit to find it in element, i dont have to code in front of me right now. I'm not sure if you are familiar with intellisense. Intellisense would basically allow you to put a breakpoint in the foreach statement, run the app, hover your cursor over the element text in the above code, and look through it's child and parent elements to look for the property you want to retrieve from it. –  Jul 05 '13 at 14:32
  • intellisense doesn't show anything after a full stop on element after declaring movie = element.InnerText – totalnoob Jul 05 '13 at 14:55
  • And you put the breakpoint inside the foreach? Also, look at the element in foreach (XmlElement element in MovieXML) –  Jul 05 '13 at 14:58
  • the innerText of the first element is 1DarkKnight, second one is 2IronMan – totalnoob Jul 05 '13 at 15:37
  • I just tried this. It works. movieModel.Movies.Add(new Movie(){movie = element.InnerText, id = Int32.Parse(element.LastChild.InnerText)}); –  Jul 05 '13 at 15:51
  • Amila's answer is the one I gave you originally that you told Vismari you didn't want. Your words concerning xmlserialization were "I'm still new to .net/c#, havn't gotten that far yet. would that be the most efficient way of achieving what I need?". –  Jul 06 '13 at 13:04