当前位置 : 首页 » 互动问答 » 正文

Convert XML String to Object

分类 : 互动问答 | 发布时间 : 2010-07-06 23:04:49 | 评论 : 11 | 浏览 : 253954 | 喜欢 : 127

I am receiving XML strings over a socket, and would like to convert these to C# objects.

The messages are of the form:

<msg>
   <id>1</id>
   <action>stop</action>
</msg>

I am new to .Net, and am not sure the best practice for performing this. I've used JAXB for Java before, and wasn't sure if there is something similar, or if this would be handled a different way.

回答(11)

  • 1楼
  • You need to use the xsd.exe tool which gets installed with the Windows SDK into a directory something similar to:

    C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin
    

    And on 64-bit computers:

    C:\Program Files (x86)\Microsoft SDKs\Windows\v6.0A\bin
    

    And on Windows 10 computers:

    C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin
    

    On the first run, you use xsd.exe and you convert your sample XML into a XSD file (XML schema file):

    xsd yourfile.xml
    

    This gives you yourfile.xsd, which in a second step, you can convert again using xsd.exe into a C# class:

    xsd yourfile.xsd /c
    

    This should give you a file yourfile.cs which will contain a C# class that you can use to deserialize the XML file you're getting - something like:

    XmlSerializer serializer = new XmlSerializer(typeof(msg));
    msg resultingMessage = (msg)serializer.Deserialize(new XmlTextReader("yourfile.xml"));
    

    Should work pretty well for most cases.

    Update: the XML serializer will take any stream as its input - either a file or a memory stream will be fine:

    XmlSerializer serializer = new XmlSerializer(typeof(msg));
    MemoryStream memStream = new MemoryStream(Encoding.UTF8.GetBytes(inputString));
    msg resultingMessage = (msg)serializer.Deserialize(memStream);
    

    or use a StringReader:

    XmlSerializer serializer = new XmlSerializer(typeof(msg));
    StringReader rdr = new StringReader(inputString);
    msg resultingMessage = (msg)serializer.Deserialize(rdr);
    
  • 2楼
  • You have two possibilities.

    Method 1. XSD tool


    Suppose that you have your XML file in this location C:\path\to\xml\file.xml

    1. Open Developer Command Prompt
      You can find it in Start Menu > Programs > Microsoft Visual Studio 2012 > Visual Studio Tools Or if you have Windows 8 can just start typing Developer Command Prompt in Start screen
    2. Change location to your XML file directory by typing cd /D "C:\path\to\xml"
    3. Create XSD file from your xml file by typing xsd file.xml
    4. Create C# classes by typing xsd /c file.xsd

    And that's it! You have generated C# classes from xml file in C:\path\to\xml\file.cs

    Method 2 - Paste special


    Required Visual Studio 2012+ with .Net Framework >= 4.5 as project target

    1. Copy content of your XML file to clipboard
    2. Add to your solution new, empty class file (Shift+Alt+C)
    3. Open that file and in menu click Edit > Paste special > Paste XML As Classes
      enter image description here

    And that's it!

    Usage


    Usage is very simple with this helper class:

    using System;
    using System.IO;
    using System.Web.Script.Serialization; // Add reference: System.Web.Extensions
    using System.Xml;
    using System.Xml.Serialization;
    
    namespace Helpers
    {
        internal static class ParseHelpers
        {
            private static JavaScriptSerializer json;
            private static JavaScriptSerializer JSON { get { return json ?? (json = new JavaScriptSerializer()); } }
    
            public static Stream ToStream(this string @this)
            {
                var stream = new MemoryStream();
                var writer = new StreamWriter(stream);
                writer.Write(@this);
                writer.Flush();
                stream.Position = 0;
                return stream;
            }
    
    
            public static T ParseXML<T>(this string @this) where T : class
            {
                var reader = XmlReader.Create(@this.Trim().ToStream(), new XmlReaderSettings() { ConformanceLevel = ConformanceLevel.Document });
                return new XmlSerializer(typeof(T)).Deserialize(reader) as T;
            }
    
            public static T ParseJSON<T>(this string @this) where T : class
            {
                return JSON.Deserialize<T>(@this.Trim());
            }
        }
    }
    

    All you have to do now, is:

        public class JSONRoot
        {
            public catalog catalog { get; set; }
        }
        // ...
    
        string xml = File.ReadAllText(@"D:\file.xml");
        var catalog1 = xml.ParseXML<catalog>();
    
        string json = File.ReadAllText(@"D:\file.json");
        var catalog2 = json.ParseJSON<JSONRoot>();
    
  • 3楼
  • Try this method to Convert Xml to an object. It is made for exactly what you are doing:

    protected T FromXml<T>(String xml)
    {
        T returnedXmlClass = default(T);
    
        try
        {
            using (TextReader reader = new StringReader(xml))
            {
                try
                {
                    returnedXmlClass = 
                        (T)new XmlSerializer(typeof(T)).Deserialize(reader);
                }
                catch (InvalidOperationException)
                {
                    // String passed is not XML, simply return defaultXmlClass
                }
            }
        }
        catch (Exception ex)
        {
        }
    
        return returnedXmlClass ;        
    }
    

    Call it using this code:

    YourStrongTypedEntity entity = FromXml<YourStrongTypedEntity>(YourMsgString);
    
  • 4楼
  • Simply Run Your Visual Studio 2013 as Administration ... Copy the content of your Xml file.. Go to Visual Studio 2013 > Edit > Paste Special > Paste Xml as C# Classes It will create your c# classes according to your Xml file content.

  • 5楼
  • Just in case anyone might find this useful:

    public static class XmlConvert
    {
        public static string SerializeObject<T>(T dataObject)
        {
            if (dataObject == null)
            {
                return string.Empty;
            }
            try
            {
                using (StringWriter stringWriter = new System.IO.StringWriter())
                {
                    var serializer = new XmlSerializer(typeof(T));
                    serializer.Serialize(stringWriter, dataObject);
                    return stringWriter.ToString();
                }
            }
            catch (Exception ex)
            {
                return string.Empty;
            }
        }
    
        public static T DeserializeObject<T>(string xml)
             where T : new()
        {
            if (string.IsNullOrEmpty(xml))
            {
                return new T();
            }
            try
            {
                using (var stringReader = new StringReader(xml))
                {
                    var serializer = new XmlSerializer(typeof(T));
                    return (T)serializer.Deserialize(stringReader);
                }
            }
            catch (Exception ex)
            {
                return new T();
            }
        }
    }
    

    You can call it using:

    MyCustomObject myObject = new MyCustomObject();
    string xmlString = XmlConvert.SerializeObject(myObject)
    myObject = XmlConvert.DeserializeObject<MyCustomObject>(xmlString);
    
  • 7楼
  • You can generate class as described above, or write them manually:

    [XmlRoot("msg")]
    public class Message
    {
        [XmlElement("id")]
        public string Id { get; set; }
        [XmlElement("action")]
        public string Action { get; set; }
    }
    

    Then you can use ExtendedXmlSerializer to serialize and deserialize.

    Instalation You can install ExtendedXmlSerializer from nuget or run the following command:

    Install-Package ExtendedXmlSerializer
    

    Serialization:

    var serializer = new ConfigurationContainer().Create();
    var obj = new Message();
    var xml = serializer.Serialize(obj);
    

    Deserialization

    var obj2 = serializer.Deserialize<Message>(xml);
    

    This serializer support:

    • Deserialization xml from standard XMLSerializer
    • Serialization class, struct, generic class, primitive type, generic list and dictionary, array, enum
    • Serialization class with property interface
    • Serialization circular reference and reference Id
    • Deserialization of old version of xml
    • Property encryption
    • Custom serializer
    • Support XmlElementAttribute and XmlRootAttribute
    • POCO - all configurations (migrations, custom serializer...) are outside the class

    ExtendedXmlSerializer support .NET 4.5 or higher and .NET Core. You can integrate it with WebApi and AspCore.

  • 8楼
  • If you have the xsd of the xml message then you can generate c# classes using the .Net xsd.exe tool.

    This .Net classes can then be used to generate the xml.

  • 9楼
  • In addition to the other answers here you can naturally use the XmlDocument class, for XML DOM-like reading, or the XmlReader, fast forward-only reader, to do it "by hand".

  • 10楼
  • Simplifying Damian's great answer,

    public static T ParseXml<T>(this string value) where T : class
    {
        var xmlSerializer = new XmlSerializer(typeof(T));
        using (var textReader = new StringReader(value))
        {
            return (T) xmlSerializer.Deserialize(textReader);
        }
    }
    
  • 11楼
  • public string Serialize<T>(T settings)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(T));
        StringWriter outStream = new StringWriter();
        serializer.Serialize(outStream, settings);
        return outStream.ToString();
    }
    

相关阅读:

How do I make calls to a REST api using C#?

What is the best way to implement a "timer"?

Converting string format to datetime in mm/dd/yyyy

Convert HTML to PDF in .NET

Sorting rows in a data table

Best way to read a large file into a byte array in C#?

Run Command Prompt Commands

How do I use Assert to verify that an exception has been thrown?

Merge two (or more) lists into one, in C# .NET

How to open a web page from my application?