我正在通过套接字接收XML字符串,并希望将它们转换为C#对象。
消息的格式如下:
<msg>
<id>1</id>
<action>stop</action>
</msg>
我是.Net的新手,并不确定执行此操作的最佳做法。我之前使用过JAXB for Java,并且不确定是否有类似的东西,或者是否会以不同的方式处理。
答案 0 :(得分:247)
您需要将随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);
答案 1 :(得分:194)
你有两种可能性。
<小时/> 假设您的XML文件位于此位置
C:\path\to\xml\file.xml
Start Menu > Programs > Microsoft Visual Studio 2012 > Visual Studio Tools
找到它
或者如果您有Windows 8,只需在开始屏幕cd /D "C:\path\to\xml"
xsd file.xml
xsd /c file.xsd
就是这样!您已在C:\path\to\xml\file.cs
<小时/> 要求Visual Studio 2012+与.Net Framework&gt; = 4.5作为项目目标
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>();
答案 2 :(得分:44)
尝试使用此方法将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);
答案 3 :(得分:11)
只需将Visual Studio 2013作为管理运行... 复制Xml文件的内容.. 转到Visual Studio 2013&gt;编辑&gt;选择性粘贴&gt;将Xml粘贴为C#类 它将根据您的Xml文件内容创建您的c#类。
答案 4 :(得分:5)
万一有人会发现这个有用:
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);
答案 5 :(得分:2)
您可以使用xsd.exe在.Net中创建模式绑定类,然后使用XmlSerializer来反序列化字符串:http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.deserialize.aspx
答案 6 :(得分:2)
您可以如上所述生成类,或手动编写它们:
[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);
此序列化程序支持:
ExtendedXmlSerializer支持 .NET 4.5 或更高版本以及 .NET Core 。您可以将它与WebApi和AspCore集成。
答案 7 :(得分:0)
如果你有xml消息的xsd,那么你可以使用.Net xsd.exe工具生成c#类。
然后可以使用此.Net类生成xml。
答案 8 :(得分:0)
除了这里的其他答案之外,你可以自然地使用XmlDocument类,用于类似XML DOM的阅读,或XmlReader,快速前向阅读器,“手动”执行此操作
答案 9 :(得分:0)
简化达米安的好答案,
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);
}
}
答案 10 :(得分:0)
使用高级xsd到c#类生成工具的另一种方法:xsd2code.com。这个工具非常方便和强大。它比Visual Studio的xsd.exe工具具有更多的自定义设置。可以自定义Xsd2Code ++以使用列表或数组,并支持带有许多Import语句的大型模式。
注意某些功能
答案 11 :(得分: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。
答案 12 :(得分:0)
将DTO创建为CustomObject
使用以下方法使用JAXB将XML字符串转换为DTO
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;
}
答案 13 :(得分:0)
到目前为止,我已经查看了所有答案(2020年7月24日),并且必须有一种更简单,更熟悉的方式来解决此问题,如下所示。
两种情况... :一种是XML字符串是否格式正确,即在遇到之前,它以类似<?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);
答案 14 :(得分:-5)
public string Serialize<T>(T settings)
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
StringWriter outStream = new StringWriter();
serializer.Serialize(outStream, settings);
return outStream.ToString();
}