可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am receiving XML strings over a socket, and would like to convert these to C# objects.
The messages are of the form:
<msg>
<id>1</id>
<action>stop</action>
</msg>
I am new to .Net, and am not sure the best practice for performing this. I\'ve used JAXB for Java before, and wasn\'t sure if there is something similar, or if this would be handled a different way.
回答1:
You need to use the xsd.exe
tool which gets installed with the Windows SDK into a directory something similar to:
C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0A\\bin
And on 64-bit computers:
C:\\Program Files (x86)\\Microsoft SDKs\\Windows\\v6.0A\\bin
And on Windows 10 computers:
C:\\Program Files (x86)\\Microsoft SDKs\\Windows\\v7.0A\\bin
On the first run, you use xsd.exe
and you convert your sample XML into a XSD file (XML schema file):
xsd yourfile.xml
This gives you yourfile.xsd
, which in a second step, you can convert again using xsd.exe
into a C# class:
xsd yourfile.xsd /c
This should give you a file yourfile.cs
which will contain a C# class that you can use to deserialize the XML file you\'re getting - something like:
XmlSerializer serializer = new XmlSerializer(typeof(msg));
msg resultingMessage = (msg)serializer.Deserialize(new XmlTextReader(\"yourfile.xml\"));
Should work pretty well for most cases.
Update: the XML serializer will take any stream as its input - either a file or a memory stream will be fine:
XmlSerializer serializer = new XmlSerializer(typeof(msg));
MemoryStream memStream = new MemoryStream(Encoding.UTF8.GetBytes(inputString));
msg resultingMessage = (msg)serializer.Deserialize(memStream);
or use a StringReader:
XmlSerializer serializer = new XmlSerializer(typeof(msg));
StringReader rdr = new StringReader(inputString);
msg resultingMessage = (msg)serializer.Deserialize(rdr);
回答2:
You have two possibilities.
Method 1. XSD tool
Suppose that you have your XML file in this location
C:\\path\\to\\xml\\file.xml
- Open Developer Command Prompt
You can find it in Start Menu > Programs > Microsoft Visual Studio 2012 > Visual Studio Tools
Or if you have Windows 8 can just start typing Developer Command Prompt in Start screen
- Change location to your XML file directory by typing
cd /D \"C:\\path\\to\\xml\"
- Create XSD file from your xml file by typing
xsd file.xml
- Create C# classes by typing
xsd /c file.xsd
And that\'s it! You have generated C# classes from xml file in C:\\path\\to\\xml\\file.cs
Method 2 - Paste special
Required Visual Studio 2012+ with .Net Framework >= 4.5 as project target
- Copy content of your XML file to clipboard
- Add to your solution new, empty class file (Shift+Alt+C)
- Open that file and in menu click
Edit > Paste special > Paste XML As Classes
And that\'s it!
Usage
Usage is very simple with this helper class:
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());
}
}
}
All you have to do now, is:
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:
Try this method to Convert Xml to an object. It is made for exactly what you are doing:
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 ;
}
Call it using this code:
YourStrongTypedEntity entity = FromXml<YourStrongTypedEntity>(YourMsgString);
回答4:
Simply Run Your Visual Studio 2013 as Administration ...
Copy the content of your Xml file..
Go to Visual Studio 2013 > Edit > Paste Special > Paste Xml as C# Classes
It will create your c# classes according to your Xml file content.
回答5:
Just in case anyone might find this useful:
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();
}
}
}
You can call it using:
MyCustomObject myObject = new MyCustomObject();
string xmlString = XmlConvert.SerializeObject(myObject)
myObject = XmlConvert.DeserializeObject<MyCustomObject>(xmlString);
回答6:
You can use xsd.exe to create schema bound classes in .Net then XmlSerializer to Deserialize the string : http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.deserialize.aspx
回答7:
You can generate class as described above, or write them manually:
[XmlRoot(\"msg\")]
public class Message
{
[XmlElement(\"id\")]
public string Id { get; set; }
[XmlElement(\"action\")]
public string Action { get; set; }
}
Then you can use ExtendedXmlSerializer to serialize and deserialize.
Instalation
You can install ExtendedXmlSerializer from nuget or run the following command:
Install-Package ExtendedXmlSerializer
Serialization:
var serializer = new ConfigurationContainer().Create();
var obj = new Message();
var xml = serializer.Serialize(obj);
Deserialization
var obj2 = serializer.Deserialize<Message>(xml);
This serializer support:
- Deserialization xml from standard XMLSerializer
- Serialization class, struct, generic class, primitive type, generic list and dictionary, array, enum
- Serialization class with property interface
- Serialization circular reference and reference Id
- Deserialization of old version of xml
- Property encryption
- Custom serializer
- Support XmlElementAttribute and XmlRootAttribute
- POCO - all configurations (migrations, custom serializer...) are outside the class
ExtendedXmlSerializer support .NET 4.5 or higher and .NET Core. You can integrate it with WebApi and AspCore.
回答8:
If you have the xsd of the xml message then you can generate c# classes using the .Net xsd.exe tool.
This .Net classes can then be used to generate the xml.
回答9:
In addition to the other answers here you can naturally use the XmlDocument class, for XML DOM-like reading, or the XmlReader, fast forward-only reader, to do it \"by hand\".
回答10:
Simplifying Damian\'s great answer,
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:
public string Serialize<T>(T settings)
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
StringWriter outStream = new StringWriter();
serializer.Serialize(outStream, settings);
return outStream.ToString();
}