将XML String转换为Object

Ste*_*eve 168 c# xml xml-serialization xml-parsing

我通过套接字接收XML字符串,并希望将它们转换为C#对象.

消息的形式如下:

<msg>
   <id>1</id>
   <action>stop</action>
</msg>
Run Code Online (Sandbox Code Playgroud)

我是.Net的新手,并不确定执行此操作的最佳做​​法.我之前使用过JAXB for Java,并且不确定是否有类似的东西,或者是否会以不同的方式处理.

mar*_*c_s 264

您需要使用xsd.exe随Windows SDK安装的工具进入类似于以下目录的目录:

C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin
Run Code Online (Sandbox Code Playgroud)

在64位计算机上:

C:\Program Files (x86)\Microsoft SDKs\Windows\v6.0A\bin
Run Code Online (Sandbox Code Playgroud)

在Windows 10计算机上:

C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin
Run Code Online (Sandbox Code Playgroud)

在第一次运行时,您使用xsd.exe并将示例XML转换为XSD文件(XML架构文件):

xsd yourfile.xml
Run Code Online (Sandbox Code Playgroud)

这样yourfile.xsd,您可以在第二步中再次使用xsd.exeC#类进行转换:

xsd yourfile.xsd /c
Run Code Online (Sandbox Code Playgroud)

这应该为您提供一个文件yourfile.cs,其中包含一个C#类,您可以使用它来反序列化您正在获取的XML文件 - 例如:

XmlSerializer serializer = new XmlSerializer(typeof(msg));
msg resultingMessage = (msg)serializer.Deserialize(new XmlTextReader("yourfile.xml"));
Run Code Online (Sandbox Code Playgroud)

对大多数情况应该很好.

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

XmlSerializer serializer = new XmlSerializer(typeof(msg));
MemoryStream memStream = new MemoryStream(Encoding.UTF8.GetBytes(inputString));
msg resultingMessage = (msg)serializer.Deserialize(memStream);
Run Code Online (Sandbox Code Playgroud)

或使用StringReader:

XmlSerializer serializer = new XmlSerializer(typeof(msg));
StringReader rdr = new StringReader(inputString);
msg resultingMessage = (msg)serializer.Deserialize(rdr);
Run Code Online (Sandbox Code Playgroud)

  • @Steve:您可以打开StringReader并传递Deserialize方法.StringReader派生自TextReader. (5认同)
  • 这个网站比xsd工具IMO容易得多:http://xmltocsharp.azurewebsites.net/ (5认同)
  • @Steve:是的,我会 - 反序列化到一个对象中并且能够对对象的属性进行挖掘似乎比使用XML元素,属性,子节点等进行大量摆动要容易得多.如果对于Linq-to-XML,它是很好的XML是不规则的,并且一直在变化,或者提前不知道. (2认同)

Dam*_*iel 212

你有两种可能性.

方法1. XSD工具


假设您在此位置拥有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. 通过键入来创建xml文件中的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. 添加到您的解决方案新的空类文件(Shift+ Alt+ C)
  3. 打开该文件并单击菜单 Edit > Paste special > Paste XML As Classes
    在此输入图像描述

就是这样!

用法


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

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());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

你现在要做的就是:

    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>();
Run Code Online (Sandbox Code Playgroud)

  • 方法2非常有用!感谢那.我不知道存在. (10认同)
  • 干杯.re:方法2,你必须以.net 4.5为目标,否则该选项不可用. (7认同)
  • “将XML作为类粘贴”需要安装Visual Studio的WCF工作负载。 (2认同)

RJ.*_*RJ. 46

尝试使用此方法将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 ;        
}
Run Code Online (Sandbox Code Playgroud)

使用以下代码调用它:

YourStrongTypedEntity entity = FromXml<YourStrongTypedEntity>(YourMsgString);
Run Code Online (Sandbox Code Playgroud)

  • 得到此错误xmlns =''>没有预期."},任何想法? (6认同)

小智 11

只需将Visual Studio 2013作为管理运行...复制Xml文件的内容..转到Visual Studio 2013>编辑>选择性粘贴>将Xml粘贴为C#类它将根据您的Xml文件内容创建c#类.


Woj*_*pl2 8

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

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

然后您可以使用ExtendedXmlSerializer进行序列化和反序列化。

安装 您可以从nuget安装 ExtendedXmlSerializer或运行以下命令:

Install-Package ExtendedXmlSerializer
Run Code Online (Sandbox Code Playgroud)

序列化:

var serializer = new ConfigurationContainer().Create();
var obj = new Message();
var xml = serializer.Serialize(obj);
Run Code Online (Sandbox Code Playgroud)

反序列化

var obj2 = serializer.Deserialize<Message>(xml);
Run Code Online (Sandbox Code Playgroud)

此序列化程序支持:

  • 从标准 XMLSerializer 反序列化 xml
  • 序列化类、结构体、泛型类、原始类型、泛型列表和字典、数组、枚举
  • 带有属性接口的序列化类
  • 序列化循环引用和引用Id
  • 旧版xml反序列化
  • 属性加密
  • 自定义序列化程序
  • 支持 XmlElementAttribute 和 XmlRootAttribute
  • POCO - 所有配置(迁移、自定义序列化程序...)都在类之外

ExtendedXmlSerializer 支持.NET 4.5或更高版本和.NET Core。您可以将其与 WebApi 和 AspCore 集成。


Raz*_*zer 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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

你可以用它来调用它:

MyCustomObject myObject = new MyCustomObject();
string xmlString = XmlConvert.SerializeObject(myObject)
myObject = XmlConvert.DeserializeObject<MyCustomObject>(xmlString);
Run Code Online (Sandbox Code Playgroud)