How to deserialize xml to object [duplicate]
Asked Answered
P

2

148
<StepList>
  <Step>
    <Name>Name1</Name>
    <Desc>Desc1</Desc>
  </Step>
  <Step>
    <Name>Name2</Name>
    <Desc>Desc2</Desc>
  </Step>
</StepList>

I have this XML, How should i model the Class so i will be able to deserialize it using XmlSerializer object?

Pathogenesis answered 9/5, 2012 at 14:41 Comment(0)
M
271

Your classes should look like this

[XmlRoot("StepList")]
public class StepList
{
    [XmlElement("Step")]
    public List<Step> Steps { get; set; }
}

public class Step
{
    [XmlElement("Name")]
    public string Name { get; set; }
    [XmlElement("Desc")]
    public string Desc { get; set; }
}

Here is my testcode.

string testData = @"<StepList>
                        <Step>
                            <Name>Name1</Name>
                            <Desc>Desc1</Desc>
                        </Step>
                        <Step>
                            <Name>Name2</Name>
                            <Desc>Desc2</Desc>
                        </Step>
                    </StepList>";

XmlSerializer serializer = new XmlSerializer(typeof(StepList));
using (TextReader reader = new StringReader(testData))
{
    StepList result = (StepList) serializer.Deserialize(reader);
}

If you want to read a text file you should load the file into a FileStream and deserialize this.

using (FileStream fileStream = new FileStream("<PathToYourFile>", FileMode.Open)) 
{
    StepList result = (StepList) serializer.Deserialize(fileStream);
}
Madelaine answered 9/5, 2012 at 14:56 Comment(8)
[XmlElement("Step")] is the key - to remove "step" nesting in XML (<Step><Step><Name>...)Rachele
i don't understand. Sure [XmlElement("Step")] is the key, is right. What you mean with "- to remove "step" nesting in XML (<Step><Step><Name>...)". Thank you!Madelaine
it was not for you but for others who might be reading this answer :) if you do not have [XmlElement] then resulting XML will be like that: <Step><Step><Name>Name1</Name><Step><Name>Name2</Name></Step></Step>. It took me a while some time ago to figure out how to remove outer <Step> block.Rachele
I tried without [XmlElement("Step")] in class and it is workingGraphic
Why do you use "using"? Is there any benefit in comparison with this aproach: XmlSerializer serializer = new XmlSerializer(typeof(StepList)); TextReader reader = new StringReader(testData); StepList result = (StepList) serializer.Deserialize(reader);Maugre
@Maugre Yes, there are benefits of using "using". https://mcmap.net/q/108572/-ioexception-the-process-cannot-access-the-file-39-file-path-39-because-it-is-being-used-by-another-processSlang
@Maugre yes it guarantees cleanup of any object that is derived from IDisposable, in my personal experience, if I'm using anything that derives from IDisposable, I automatically calls .Dispose when it goes out of scope and ensures good cleanup of unmanaged resource.Kariekaril
This answer seems incomplete because when I use it with a class generated by pasting the XML into an empty class via Paste Special, I get Cannot deserialize type 'Sweeper365_DAL.OutboundEmailMessage' because it contains property 'message' which has no public setter.Revetment
C
43

The comments above are correct. You're missing the decorators. If you want a generic deserializer you can use this.

public static T DeserializeXMLFileToObject<T>(string XmlFilename)
{
    T returnObject = default(T);
    if (string.IsNullOrEmpty(XmlFilename)) return default(T);

    try
    {
        StreamReader xmlStream = new StreamReader(XmlFilename);
        XmlSerializer serializer = new XmlSerializer(typeof(T));
        returnObject = (T)serializer.Deserialize(xmlStream);
    }
    catch (Exception ex)
    {
        ExceptionLogger.WriteExceptionToConsole(ex, DateTime.Now);
    }
    return returnObject;
}

Then you'd call it like this:

MyObjType MyObj = DeserializeXMLFileToObject<MyObjType>(FilePath);
Chippy answered 3/6, 2016 at 16:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.