blah blah blah is here! blah blah » Close

up1down
link

I am attempting to deserialize an XML file that looks like so:

<?xml version="1.0"?>
<cameras>
<camera name="z1485" id="0">
<mode name="Video" cmd="96">
<resolution name="1280x720" value="0"/>
<resolution name="640x480" value="1"/>
<resolution name="320x240" value="2"/>
</mode>
</camera>
<camera name="a950" id="2">
<mode name="Video" cmd="96">
<resolution name="1280x720" value="0"/>
<resolution name="640x480" value="1"/>
</mode>
</camera>
</cameras>


Using the following code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;


namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{

List<Camera> Cameras = new List<Camera>();

XmlSerializer deserializer = new XmlSerializer(typeof(List<Camera>));
TextReader textReader = new StreamReader("cameras.xml");
Cameras = (List<Camera>)deserializer.Deserialize(textReader);
textReader.Close();

}
}

[XmlRootAttribute("camera",Namespace="",IsNullable=false)]
public class Camera
{

[XmlElement("mode")]
List<Mode> Modes;

public Camera()
{
Modes = new List<Mode>();
}

}

public class Mode
{
[XmlElement("resolution")]
List<Resolution> Resolution;

[XmlAttribute("name")]
public string Name { get; set; }
[XmlAttribute("id")]
public byte Id { get; set; }

public Mode()
{
Resolution = new List<Resolution>();
}
}


public class Resolution
{
[XmlAttribute("name")]
public string name {get; set;}
[XmlAttribute("value")]
public byte value { get; set; }

}


}


There will be many camera entries. There will be many modes per camera. There will also be more properties of a single camera mode. This is a very simple xml document for now. I want to deserialize this data into a list of cameras. The list of cameras will be made up of a list of modes (and perhaps other elements). The list of modes will be made up of various lists of elements (like resolution).

Now, when I run the above the deserialize process throws an 'InvalidOperationException' and tells me that 'There is an error in XML document (2,2).

Any thoughts?

last answered 2 years ago

1 answers

link

You've got one or two problems there, particularly with the root node. Try the following instead:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;


namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
List<Camera> Cameras;
XmlRootAttribute root = new XmlRootAttribute();
root.ElementName = "cameras";
root.Namespace = "";
root.IsNullable = false;
XmlSerializer deserializer = new XmlSerializer(typeof(List<Camera>), root);
TextReader textReader = new StreamReader("cameras.xml");
Cameras = (List<Camera>)deserializer.Deserialize(textReader);
textReader.Close();

// print out results
Console.Clear();
foreach(Camera c in Cameras)
{
Console.WriteLine("Camera Name = {0}, Id = {1}\n", c.Name, c.Id);
foreach(Mode m in c.Modes)
{
Console.WriteLine(" Mode Name = {0}, Cmd = {1}\n", m.Name, m.Cmd);
foreach(Resolution r in m.Resolutions)
{
Console.WriteLine(" Resolution Name = {0}, Value = {1}", r.Name, r.Value);
}
}
Console.WriteLine();
}
Console.ReadKey();
}
}

[XmlType("camera")]
public class Camera
{
[XmlAttribute("name")]
public string Name { get; set; }

[XmlAttribute("id")]
public string Id { get; set; }

[XmlElement("mode")]
public List<Mode> Modes;

public Camera()
{
Modes = new List<Mode>();
}

}

public class Mode
{
[XmlElement("resolution")]
public List<Resolution> Resolutions;

[XmlAttribute("name")]
public string Name { get; set; }

[XmlAttribute("cmd")]
public byte Cmd { get; set; }

public Mode()
{
Resolutions = new List<Resolution>();
}
}


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

[XmlAttribute("value")]
public byte Value { get; set; }

}

}

eeboy
499

Thanks Vulpes!!! You don't know what XML deserialization has just done for my life! :) If you'd have seen how I was parsing my XML file... well... I won't go there. :)

eeboy
499

The [XmlAttribute] and [XmlElement] are pretty intuitive to me but what does [XmlType("camera")] do?

vulpes
17279

Yes, once you get your classes right, XML deserialization is much easier than trying to parse the file directly with XmlReader, XmlDocument etc. As we're deserializing directly to a List<Camera), the deserializer needs a way of associating the Camera class with the camera (small 'c') elements in the Xml file. The XmlType attribute does this.

Feedback