将XML String转换为Object

问题描述 投票:149回答:12

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

消息的形式如下:

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

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

c# xml xml-parsing xml-serialization
12个回答
254
投票

您需要将随Windows SDK一起安装的xsd.exe工具用于类似于以下目录:

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

0
投票

简化Damian的绝佳答案,

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

0
投票

使用高级xsd到c#类生成工具的另一种方法:xsd2code.com。这个工具非常方便和强大。它比Visual Studio中的xsd.exe工具有更多的自定义。可以自定义Xsd2Code ++以使用Lists或Arrays,并支持包含大量Import语句的大型模式。

注意一些功能,

  • 从XSD架构或XML文件生成业务对象到灵活的C#或Visual Basic代码。
  • 支持框架2.0到4.x.
  • 支持强类型集合(List,ObservableCollection,MyCustomCollection)。
  • 支持自动属性。
  • 生成XML读写方法(序列化/反序列化)。
  • 数据绑定支持(WPF,Xamarin)。
  • WCF(DataMember属性)。
  • XML编码支持(UTF-8/32,ASCII,Unicode,自定义)。
  • Camel case / Pascal Case支持。
  • 限制支持([StringLengthAttribute = true / false],[RegularExpressionAttribute = true / false],[RangeAttribute = true / false])。
  • 支持大而复杂的XSD文件。
  • 支持DotNet Core和标准

0
投票

我知道这个问题已经过时了,但我偶然发现它并且我得到的答案不同于其他所有人:-)

通常的方式(如上面提到的那样)是生成一个类并对你的xml进行反序列化。

但是(警告:这里无耻的自我推销)我刚刚发布了一个你不需要的nuget包,here。你去吧:

string xml = System.IO.File.ReadAllText(@"C:\test\books.xml");
var book = Dandraka.XmlUtilities.XmlSlurper.ParseText(xml);

这就是字面意思,没有别的需要。而且,最重要的是,如果您的xml发生变化,您的对象也会自动更改。

如果您想直接下载dll,那么github页面就是here


-5
投票
public string Serialize<T>(T settings)
{
    XmlSerializer serializer = new XmlSerializer(typeof(T));
    StringWriter outStream = new StringWriter();
    serializer.Serialize(outStream, settings);
    return outStream.ToString();
}

198
投票

你有两种可能性。

方法1. XSD工具


Suppose that you have your XML file in this location C:\path\to\xml\file.xml
  1. 打开开发人员命令提示符 您可以在Start Menu > Programs > Microsoft Visual Studio 2012 > Visual Studio Tools中找到它或者如果您有Windows 8,只需在“开始”屏幕中键入Developer Command Prompt即可
  2. 键入cd /D "C:\path\to\xml",将位置更改为XML文件目录
  3. 键入xsd file.xml,从xml文件创建XSD文件
  4. 键入xsd /c file.xsd创建C#类

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

方法2 - 粘贴特殊


Required Visual Studio 2012+ with .Net Framework >= 4.5 as project target
  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());
        }
    }
}

你现在要做的就是:

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

45
投票

尝试使用此方法将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);

11
投票

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


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

3
投票

您可以按上述方法生成类,也可以手动编写它们:

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

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

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

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的反序列化
  • 属性加密
  • 自定义序列化器
  • 支持XmlElementAttribute和XmlRootAttribute
  • POCO - 所有配置(迁移,自定义序列化程序......)都在类之外

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


2
投票

您可以使用xsd.exe在.Net中创建模式绑定类,然后使用XmlSerializer来反序列化字符串:http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.deserialize.aspx


0
投票

如果你有xml消息的xsd,那么你可以使用.Net xsd.exe工具生成c#类。

然后可以使用此.Net类生成xml。


0
投票

除了这里的其他答案,你可以自然地使用XmlDocument类,用于类似XML DOM的阅读,或者XmlReader,快速前向阅读器,“手动”执行。

© www.soinside.com 2019 - 2024. All rights reserved.