代码之家  ›  专栏  ›  技术社区  ›  Steve

将XML字符串转换为对象

  •  143
  • Steve  · 技术社区  · 14 年前

    我正在通过套接字接收XML字符串,并希望将这些字符串转换为C对象。

    消息的形式如下:

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

    我刚接触.NET,不确定执行此操作的最佳实践。以前我使用JAXB做Java,不确定是否有类似的东西,或者如果这是一种不同的方式。

    12 回复  |  直到 6 年前
        1
  •  241
  •   marc_s    9 年前

    你需要使用 xsd.exe 与Windows SDK一起安装到目录中的工具,类似于:

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

    在64位计算机上:

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

    在Windows 10计算机上:

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

    在第一次跑步时, XSD-EXE 然后将示例XML转换为XSD文件(XML模式文件):

    xsd yourfile.xml
    

    这给了你 yourfile.xsd ,在第二步中,可以使用 XSD-EXE 分为C类:

    xsd yourfile.xsd /c
    

    这应该给你一个文件 yourfile.cs 它将包含一个C类,您可以使用该类来反序列化正在获取的XML文件-类似于:

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

    在大多数情况下都能很好地工作。

    更新: XML序列化程序将以任何流作为输入-文件或内存流都可以:

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

    或者使用StringReader:

    XmlSerializer serializer = new XmlSerializer(typeof(msg));
    StringReader rdr = new StringReader(inputString);
    msg resultingMessage = (msg)serializer.Deserialize(rdr);
    
        2
  •  185
  •   Tommy    11 年前

    你有两种可能。

    < H2>方法1。 xsd tool


    假设您的XML文件位于此位置 c:\path\to\xml\file.xml
    1. 打开开发人员命令提示符 您可以在 开始菜单>程序>Microsoft Visual Studio 2012>Visual Studio工具中找到它 或者,如果您有Windows 8,可以开始键入 developer command prompt in start screen
    2. 通过键入 c d/d“c:\path\to\xml”,将位置更改为XML文件目录
    3. 通过键入 xsd file.xml从XML文件创建 xsd file
    4. 通过键入 xsd/c file.xsd,创建 c类

    就这样!您已经在 c:\path\to\xml\file.cs中从XML文件生成了C类

    方法2-特殊粘贴


    所需的Visual Studio 2012+,其中.NET Framework=4.5是项目目标
    1. 将XML文件的内容复制到剪贴板
    2. 添加到解决方案中新的空类文件( shift >+ alt >+ c )。
    3. 打开该文件,然后在菜单中单击 edit>Paste special>Paste XML as classes.

    就这样!

    用法


    这个助手类的用法非常简单:

    使用系统;
    使用system.io;
    使用system.web.script.serialization;//添加引用:system.web.extensions
    使用system.xml;
    使用system.xml.serialization;
    
    命名空间帮助程序
    {
    内部静态类分析器帮助程序
    {
    私有静态javascriptserializer json;
    私有静态javascriptserializer json get返回json??(json=new javascriptserializer());
    
    公共静态流到流(此字符串@this)
    {
    var stream=new memoryStream();
    var writer=新的stream writer(stream);
    writer.write(@这个);
    作家FrHuSE();
    流.位置=0;
    回流;
    }
    
    
    public static t parseXML<t>(this string@this)其中t:class
    {
    var reader=xmlreader.create(@this.trim().tostream(),new xmlreadersettings()conforceLevel=conforceLevel.document);
    返回新的XmlSerializer(typeof(t))。将(reader)反序列化为t;
    }
    
    public static t parsejson<t>(this string@this)其中t:class
    {
    返回json.deserialize<t>(@this.trim());
    }
    }
    }
    < /代码> 
    
    

    你现在要做的就是:

    public class jsonroot
    {
    公共目录目录get;set;
    }
    /…
    
    字符串xml=file.readalltext(@“d:\file.xml”);
    var catalog1=xml.parsexml<catalog>();
    
    string json=file.readalltext(@“d:\file.json”);
    var catalog2=json.parsejson<jsonroot>();
    < /代码> 
    
    
    


    假设您的XML文件在这个位置C:\path\to\xml\file.xml
    1. 正常开放开发者命令提示
      你可以在里面找到它Start Menu > Programs > Microsoft Visual Studio 2012 > Visual Studio Tools 或者如果您有Windows 8,可以开始键入开发者命令提示在里面启动屏幕
    2. 通过键入更改XML文件目录的位置cd /D "C:\path\to\xml"
    3. 创造XSD文件通过键入xsd file.xml
    4. 创造C类通过打字xsd /c file.xsd

    就这样!您已经从中的XML文件生成了C类C:\path\to\xml\file.cs

    方法2-特殊粘贴


    所需的Visual Studio 2012+,其中.NET Framework=4.5是项目目标
    1. 将XML文件的内容复制到剪贴板
    2. 添加到解决方案中新的空类文件(换档+中高音+C)
    3. 打开该文件并在菜单中单击Edit > Paste special > Paste XML As Classes
      enter image description here

    就这样!

    用法


    这个助手类的用法非常简单:

    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());
            }
        }
    }
    

    你现在要做的就是:

        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
  •  42
  •   Lee Taylor Dejan.S    11 年前

    尝试使用此方法将XML转换为对象。它完全是为你所做的:

    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 ;        
    }
    

    使用以下代码调用它:

    YourStrongTypedEntity entity = FromXml<YourStrongTypedEntity>(YourMsgString);
    
        4
  •  8
  •   user2667652    10 年前

    只需以管理身份运行Visual Studio 2013… 复制XML文件的内容.. 转到Visual Studio 2013>编辑>粘贴特殊的>将XML粘贴为C类 它将根据XML文件内容创建C类。

        5
  •  5
  •   Rasmus-E    6 年前

    以防有人发现这一点有用:

    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();
            }
        }
    }
    

    您可以使用以下方法调用它:

    MyCustomObject myObject = new MyCustomObject();
    string xmlString = XmlConvert.SerializeObject(myObject)
    myObject = XmlConvert.DeserializeObject<MyCustomObject>(xmlString);
    
        6
  •  2
  •   Skurmedel    14 年前

    可以使用xsd.exe在.NET中创建绑定到架构的类,然后使用xmlserializer反序列化字符串: http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.deserialize.aspx

        7
  •  2
  •   user1477388    6 年前

    您可以如上所述生成类,或者手动编写类:

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

    然后你可以用 ExtendedXmlSerializer 序列化和反序列化。

    分期付款 可以从安装ExtendedXmlSerializer nuget 或运行以下命令:

    Install-Package ExtendedXmlSerializer
    

    序列化:

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

    反序列化

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

    此序列化程序支持:

    • 从标准XmlSerializer反序列化XML
    • 序列化类、结构、泛型类、基元类型、泛型列表和字典、数组、枚举
    • 具有属性接口的序列化类
    • 序列化循环引用和引用ID
    • 旧版本XML的反序列化
    • 属性加密
    • 自定义序列化程序
    • 支持xmlementattribute和xmlrootattribute
    • poco-所有配置(迁移、自定义序列化程序…)都在类之外

    扩展的XmlSerializer支持 .NET 4.5 或更高 网络核心 . 您可以将它与WebAPI和Aspcore集成。

        8
  •  0
  •   Amitabh    14 年前

    如果您拥有XML消息的XSD,那么可以使用.NET XSD.exe工具生成C类。

    然后可以使用这个.NET类来生成XML。

        9
  •  0
  •   Skurmedel    14 年前

    除了这里的其他答案,您还可以自然地使用 XmlDocument 类,用于类似于读取的XML DOM,或 XmlReader 快速前进,只有读者,做它“手”。

        10
  •  0
  •   Sam Jazz    6 年前

    简化达米安的伟大答案,

    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
  •  0
  •   Dmitry Joshua Enos    6 年前

    另一种使用高级XSD到C类生成工具的方法是:xsd2code.com。这个工具非常方便和强大。它比Visual Studio中的xsd.exe工具具有更多的自定义功能。XSD2code++可以定制为使用列表或数组,并支持带有大量import语句的大型模式。

    注意一些特征,

    • 从XSD模式或XML文件到灵活的C生成业务对象# 或Visual Basic代码。
    • 支持框架2.0到4.x
    • 支持强类型集合(List、ObservableCollection、MyCustomCollection)。
    • 支持自动属性。
    • 生成XML读写方法(序列化/反序列化)。
    • 数据绑定支持(WPF、Xamarin)。
    • wcf(datamember属性)。
    • XML编码支持(UTF-8/32、ASCII、Unicode、自定义)。
    • 驼色外壳/Pascal外壳支持。
    • 限制支持([StringLengThattribute=true/false],[RegularExpressionAttribute=true/false], [rangeattribute=true/false])。
    • 支持大型复杂的XSD文件。
    • 支持Dotnet核心和标准
        12
  •  -5
  •   Jim Buck    10 年前
    public string Serialize<T>(T settings)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(T));
        StringWriter outStream = new StringWriter();
        serializer.Serialize(outStream, settings);
        return outStream.ToString();
    }