提问人:Steve 提问时间:7/6/2010 最后编辑:ΩmegaManSteve 更新时间:7/1/2022 访问量:486982
将 XML 字符串转换为对象
Convert XML String to Object
问:
我正在通过套接字接收 XML 字符串,并希望将它们转换为 C# 对象。
消息的格式如下:
<msg>
<id>1</id>
<action>stop</action>
</msg>
这怎么能做到?
答:
您需要使用与 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
在第一次运行时,使用示例 XML 并将其转换为 XSD 文件(XML 架构文件):xsd.exe
xsd yourfile.xml
这为您提供了 ,在第二步中,您可以再次将其转换为 C# 类:yourfile.xsd
xsd.exe
xsd yourfile.xsd /c
这应该会给你一个文件,其中包含一个 C# 类,你可以用它来反序列化你得到的 XML 文件 - 类似于:yourfile.cs
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);
评论
如果您有 xml 消息的 xsd,则可以使用 .Net xsd.exe 工具生成 c# 类。
然后,可以使用此 .Net 类来生成 xml。
可以使用 xsd.exe 在 .Net 中创建架构绑定类,然后使用 XmlSerializer 反序列化字符串:http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.deserialize.aspx
尝试此方法将 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);
评论
除了此处的其他答案之外,您自然可以使用 XmlDocument 类(用于类似 XML DOM 的读取)或 XmlReader(仅快进读取器)来“手动”完成此操作。
public string Serialize<T>(T settings)
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
StringWriter outStream = new StringWriter();
serializer.Serialize(outStream, settings);
return outStream.ToString();
}
评论
你有两种可能性。
方法 1.XSD 工具
假设您的 XML 文件位于此位置
C:\path\to\xml\file.xml
- 打开开发人员命令提示符,
您可以在以下位置找到它 或者,如果您有Windows 8,则可以在“开始”屏幕中开始键入开发人员命令提示符Start Menu > Programs > Microsoft Visual Studio 2012 > Visual Studio Tools
- 通过键入更改 XML 文件目录的位置
cd /D "C:\path\to\xml"
- 通过键入 xml 文件创建 XSD 文件
xsd file.xml
- 通过键入创建 C# 类
xsd /c file.xsd
就是这样!您已从 xml 文件中生成了 C# 类C:\path\to\xml\file.cs
方法 2 - 特殊粘贴
必需的 Visual Studio 2012+,其中 .Net Framework >= 4.5 作为项目目标,并安装了“Windows Communication Foundation”单个组件
- 将 XML 文件的内容复制到剪贴板
- 将新的空类文件 (Shift+Alt+C)
- 打开该文件,然后在菜单中单击
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>();
评论
只需将 Visual Studio 2013 作为管理运行... 复制 Xml 文件的内容。 转到 Visual Studio 2013 >编辑>粘贴特殊>将 xml 粘贴为 C# 类 它将根据您的 Xml 文件内容创建您的 c# 类。
以防万一有人可能会觉得这很有用:
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);
评论
您可以按上述方式生成类,也可以手动编写:
[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 集成。
评论
简化达米安的精彩回答,
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);
}
}
另一种使用高级 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 Core 和标准
我知道这个问题很老了,但我偶然发现了它,我的答案与其他人不同:-)
通常的方法(正如上面的评论者所提到的)是生成一个类并反序列化你的 xml。
但是(警告:这里是无耻的自我推销)我刚刚在这里发布了一个 nuget 包,您不必使用它。你只需去:
string xml = System.IO.File.ReadAllText(@"C:\test\books.xml");
var book = Dandraka.XmlUtilities.XmlSlurper.ParseText(xml);
从字面上看就是这样,不需要其他任何东西。而且,最重要的是,如果你的 xml 发生了变化,你的对象也会自动改变。
如果您更喜欢直接下载 dll,github 页面在这里。
将 DTO 创建为 CustomObject
使用以下方法将 XML 字符串转换为 DTO 使用 JAXB
private static CustomObject getCustomObject(final String ruleStr) {
CustomObject customObject = null;
try {
JAXBContext jaxbContext = JAXBContext.newInstance(CustomObject.class);
final StringReader reader = new StringReader(ruleStr);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
customObject = (CustomObject) jaxbUnmarshaller.unmarshal(reader);
} catch (JAXBException e) {
LOGGER.info("getCustomObject parse error: ", e);
}
return customObject;
}
截至目前(2020-07-24),我已经浏览了所有答案,并且必须有一个更简单,更熟悉的方法来解决这个问题,如下所示。
两种情况...一种是如果 XML 字符串格式正确,即它以 like 或 its likes 开头,然后遇到问题中的根元素。另一个是如果它的格式不正确,即只是根元素(例如 在问题中)及其子节点。<?xml version="1.0" encoding="utf-16"?>
<msg>
<msg>
首先,它只是一个简单的类,它包含与 XML 中根节点的子节点匹配的属性,这些属性在不区分大小写的名称中。所以,从问题来看,它会是这样的......
public class TheModel
{
public int Id { get; set; }
public string Action { get; set; }
}
以下是代码的其余部分...
// These are the key using statements to add.
using Newtonsoft.Json;
using System.Xml;
bool isWellFormed = false;
string xml = = @"
<msg>
<id>1</id>
<action>stop</action>
</msg>
";
var xmlDocument = new XmlDocument();
xmlDocument.LoadXml(xml);
if (isWellFormed)
{
xmlDocument.RemoveChild(xmlDocument.FirstChild);
/* i.e. removing the first node, which is the declaration part.
Also, if there are other unwanted parts in the XML,
write another similar code to locate the nodes
and remove them to only leave the desired root node
(and its child nodes).*/
}
var serializedXmlNode = JsonConvert.SerializeXmlNode(
xmlDocument,
Newtonsoft.Json.Formatting.Indented,
true
);
var theDesiredObject = JsonConvert.DeserializeObject<TheModel>(serializedXmlNode);
下一个:SAX 和 DOM 有什么区别?
评论