Reputation: 19
I'm trying to deserialize a XML file which Looks like the following:
<xml>
<classes>
<class name="EventLog">
<attribute name="TYPE" type="int"></attribute>
<attribute name="DESCRIPTION" type="string"></attribute>
<attribute name="ISSUEDBY" type="string></attribute>
<attribute name="DATE" type="hr_clock"></attribute>
</class>
<class name="test">
<attribute name="ttt" type="int"></attribute>
<attribute name="ppp" type="string"></attribute>
<attribute name="xxx" type="string"></attribute>
<attribute name="aaa" type="hr_clock"></attribute>
</class>
</classes>
<filters>
<filter name="COILORDERFILTER">
<attribute name="COILID" type="string"></attribute>
<attribute name="RELIABID" type="string"></attribute>
</filter>
<filter name="DriveDataFilter">
<attribute name="DRIVEID" type="string"></attribute>
</filter>
</filters>
</xml>
I need only the classes between the nodes classes
. I created following classes for the deserialization:
[Serializable()]
[System.Xml.Serialization.XmlRoot("classes")]
public class ClassCollection
{
[XmlArray("class")]
[XmlArrayItem("attribute", typeof(SingleClass))]
public SingleClass[] singleClass { get; set; }
}
[Serializable()]
public class SingleClass
{
[System.Xml.Serialization.XmlAttribute("name")]
public string name { get; set; }
[System.Xml.Serialization.XmlAttribute("type")]
public string type { get; set; }
}
class Program
{
static void Main(string[] args)
{
ClassCollection classes = null;
string path = @"C:\Users\test\Desktop\Eventlog.xml";
XmlSerializer serializer = new XmlSerializer(typeof(ClassCollection));
StreamReader reader = new StreamReader(path);
try
{
classes = (ClassCollection)serializer.Deserialize(reader);
}
catch (InvalidOperationException excep)
{
Console.WriteLine(excep.ToString());
}
Console.Read();
}
}
Can anybody say me "what is wrong"?
Upvotes: 1
Views: 831
Reputation: 3970
If you can't rework your xml, your question is very similar to this one: Ignore outer elements using XmlSerializer
Personnaly, I will use XmlReader instead of XmlSerializer to deserialize your sample XML because it allows to build a model that is not heavily coupled to the XML you are reading.
Upvotes: 0
Reputation: 1062975
Here's a tip; put your sample xml in a file - my.xml
, say, then:
xsd my.xml
xsd my.xsd /classes
This creates my.cs
which matches the xml.
Alternatively: you need to understand all the markup; the root is <xml/>
, so you need [XmlRoot("xml")]
, for example. And you almost certainly mean:
[XmlArray("classes")]
[XmlArrayItem("class", typeof(SingleClass))]
public SingleClass[] singleClass { get; set; }
This works, for example:
[XmlRoot("xml")]
public class ClassCollection
{
[XmlArray("classes")]
[XmlArrayItem("class", typeof(SingleClass))]
public SingleClass[] singleClass { get; set; }
}
public class SingleClass
{
[XmlElement("attribute")]
public List<Attribute> Attributes { get; set; }
[XmlAttribute("name")]
public string Name { get; set; }
}
public class Attribute {
[XmlAttribute("name")]
public string name { get; set; }
[XmlAttribute("type")]
public string type { get; set; }
}
Upvotes: 4
Reputation: 2603
Not sure about your problem since there are no errors
but 1st:
[XmlRoot("classes")]
It means that the first XML node should be "classes" and it's "xml" right now from your example. So create a new object:
[XmlRoot("xml")]
class MyRoot {
//...
Also, usually you'll want to have something like this as your first line for the default serializer to work I think:
<?xml version="1.0" encoding="utf-8" ?>
Also, I think you have some errors in your dataclass definition. You should comment some stuff and do some tests with less data in order to understand properly what's happening.
Upvotes: 0