I'm currently working on an ASP.NET MVC 4.6 application using SQL Server 2014 as a data storage.
I need to parse a XML document from an URL, transform the XML into an object and store it into the database using Entity Framework 6.
I need to parse the XML from an URL like this:
http: //api.myserver.com/notes.xml
My XML looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<notes>
<note>
<to>Tove</to>
<from>Jane</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
<note>
<to>Doe</to>
<from>John</from>
<heading>Meeting</heading>
<body>Hello Monday!</body>
</note>
<notes>
My model class note looks like this:
public class Note
{
public string To { get; set; }
public string From { get; set; }
public string Heading { get; set; }
public string Body { get; set; }
}
My current test implementation looks like this, BUT I'm not so happy about the parsing of the XML:
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
String url = "https://www.w3schools.com/xml/note.xml";
XmlDocument doc = new XmlDocument();
doc.Load(url);
XmlElement root = doc.DocumentElement;
StringBuilder sb = new StringBuilder();
sb.Append("<note>");
foreach (XmlNode item in root)
{
sb.Append(item.OuterXml);
}
sb.Append("</note>");
var result = Deserialize<Note>(sb.ToString());
// further processing of result using EF 6
Console.ReadKey();
}
public static T Deserialize<T>(string xmlText)
{
try
{
var stringReader = new StringReader(xmlText);
var serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(stringReader);
}
catch (Exception ex)
{
throw;
}
}
}
[XmlRoot(ElementName = "note", Namespace = "")]
public class Note
{
[XmlElement("to")]
public string To { get; set; }
[XmlElement("from")]
public string From { get; set; }
[XmlElement("heading")]
public string Heading { get; set; }
[XmlElement("body")]
public string Body { get; set; }
}
}
As far as I noticed, .NET provides several approaches on how to parse XML:
XmlReader Class
XPath
XDocument
DataSet
LINQ
I was wondering, what would you use and how would u solve the parsing of the XML document from an URL using .NET and converting into an object to store it in a SQL Server DB?
Thanks for your help and consideration!!
This might help you, a serialize method and a Deserialize method.
public static string Serialize<T>(T dataToSerialize)
{
try
{
var stringwriter = new ISOEncodingStringWriter();
var serializer = new XmlSerializer(typeof(T));
var xns = new XmlSerializerNamespaces();
xns.Add(string.Empty, string.Empty);
serializer.Serialize(stringwriter, dataToSerialize, xns);
return stringwriter.ToString();
}
catch
{
throw;
}
}
public static T Deserialize<T>(string xmlText)
{
try
{
var stringReader = new System.IO.StringReader(xmlText);
var serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(stringReader);
}
catch
{
throw;
}
}
You use the method like this:
Note result = Deserialize<Note>(xmlstring);
Note note = new Note(){...};
string convertedToXML = Serialize<Note>(note);
Just remember that you need to add some data to your note class so it can actually serialize the data:
[XmlRoot(ElementName = "root", Namespace = "")]
public class Note
{
[XmlElementAttribute("To")]
public string To { get; set; }
[XmlElementAttribute("From")]
public string From { get; set; }
[XmlElementAttribute("Heading")]
public string Heading { get; set; }
[XmlElementAttribute("Body")]
public string Body { get; set; }
}
I hope it helps :)
You can use LINQ to XML to traverse the nodes of your documents and either EF or ADO.NET to store them in the DB.
You can start with this helpful tutorial: http://www.c-sharpcorner.com/UploadFile/de41d6/learning-linq-made-easy-tutorial-1/
Related
I see this question often enough, but nobody's title really seems to depict their question. I get a large response object back from a Web API that contains general response information, along with the data object I want to deserialize.
Full XML:
<?xml version="1.0"?>
<root>
<status>
<apiErrorCode>0</apiErrorCode>
<apiErrorMessage/>
<dbErrorCode>0</dbErrorCode>
<dbErrorMessage/>
<dbErrorList/>
</status>
<data>
<modelName>ReportXDTO</modelName>
<modelData>
<id>1780</id>
<reportTitle>Access Level (select) with Door Assignment</reportTitle>
<hasParameters>true</hasParameters>
<parameters>
<dataType>STRING</dataType>
<title>Access Level:</title>
<index>1</index>
<allowMulti>true</allowMulti>
<selectSql>SELECT DISTINCT [Name] FROM dbo.[Levels] WHERE [PrecisionFlag] = '0' ORDER BY [Name] </selectSql>
<values>
<value>Door 1</value>
<used>1</used>
</values>
<values>
<value>Door 2</value>
<used>1</used>
</values>
<values>
<value>Door 3</value>
<used>1</used>
</values>
</parameters>
<sourceSql>SELECT [Name], [SData] FROM [Schedules]</sourceSql>
<report/>
</modelData>
<itemReturned>1</itemReturned>
<itemTotal>1</itemTotal>
</data>
<listInfo>
<pageIdRequested>1</pageIdRequested>
<pageIdCurrent>1</pageIdCurrent>
<pageIdFirst>1</pageIdFirst>
<pageIdPrev>1</pageIdPrev>
<pageIdNext>1</pageIdNext>
<pageIdLast>1</pageIdLast>
<itemRequested>1</itemRequested>
<itemReturned>1</itemReturned>
<itemStart>1</itemStart>
<itemEnd>1</itemEnd>
<itemTotal>1</itemTotal>
</listInfo>
</root>
I only want to deserialize the modelData element. The modelData object type is dynamic, depending on the API call.
I deserialize xml in other applications, and created the following method, but don't know how to specifically ONLY get the modelData element:
public static T ConvertXmltoClass<T>(HttpResponseMessage http, string elementName) where T : new()
{
var newClass = new T();
try
{
var doc = JsonConvert.DeserializeXmlNode(http.Content.ReadAsStringAsync().Result, "root");
XmlReader reader = new XmlNodeReader(doc);
reader.ReadToFollowing(elementName);
//The xml needs to show the proper object name
var xml = reader.ReadOuterXml().Replace(elementName, newClass.GetType().Name);
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
{
var serializer = new XmlSerializer(typeof(T));
newClass = (T)serializer.Deserialize(stream);
}
}
catch (Exception e)
{
AppLog.LogException(System.Reflection.MethodBase.GetCurrentMethod().Name, e);
}
return newClass;
}
I have updated this thread multiple times now, to stay current. I started updating it with the first solution. But that solution by itself didn't solve the problem. With the code how it is right now, I get no exceptions, but don't get the xml deserialized to my object. Instead I get a new, blank object. Thoughts?
THOUGH the object type can change, here is my current object I am dealing with: (PLEASE NOTE, that I deserialize the exact xml in modelData, in the Web API)
namespace WebApiCommon.DataObjects
{
[Serializable]
public class ReportXDto
{
public ReportXDto()
{
Parameters = new List<ReportParameterXDto>();
}
public int Id { get; set; }
public string ReportTitle { get; set; }
public bool HasParameters { get; set; } = false;
public List<ReportParameterXDto> Parameters { get; set; }
public string SourceSql { get; set; }
public DataTable Report { get; set; }
}
[Serializable]
public class ReportXDto
{
public ReportXDto()
{
Parameters = new List<ReportParameterXDto>();
}
public int Id { get; set; }
public string ReportTitle { get; set; }
public bool HasParameters { get; set; } = false;
public List<ReportParameterXDto> Parameters { get; set; }
public string SourceSql { get; set; }
public DataTable Report { get; set; }
}
[Serializable]
public class ReportParameterValuesXDto
{
public string Value { get; set; } = "";
public bool Used { get; set; } = false;
}
}
Firstly, XmlSerializer is case sensitive. Thus your property names need to match the XML element names exactly -- unless overridden with an attribute that controls XML serialization such as [XmlElement(ElementName="id")]. To generate a data model with the correct casing I used http://xmltocsharp.azurewebsites.net/ which resulted in:
public class ReportParameterValuesXDto
{
[XmlElement(ElementName="value")]
public string Value { get; set; }
[XmlElement(ElementName="used")]
public string Used { get; set; }
}
public class ReportParametersXDto
{
[XmlElement(ElementName="dataType")]
public string DataType { get; set; }
[XmlElement(ElementName="title")]
public string Title { get; set; }
[XmlElement(ElementName="index")]
public string Index { get; set; }
[XmlElement(ElementName="allowMulti")]
public string AllowMulti { get; set; }
[XmlElement(ElementName="selectSql")]
public string SelectSql { get; set; }
[XmlElement(ElementName="values")]
public List<ReportParameterValuesXDto> Values { get; set; }
}
public class ReportXDto
{
[XmlElement(ElementName="id")]
public string Id { get; set; }
[XmlElement(ElementName="reportTitle")]
public string ReportTitle { get; set; }
[XmlElement(ElementName="hasParameters")]
public string HasParameters { get; set; }
[XmlElement(ElementName="parameters")]
public ReportParametersXDto Parameters { get; set; }
[XmlElement(ElementName="sourceSql")]
public string SourceSql { get; set; }
[XmlElement(ElementName="report")]
public string Report { get; set; }
}
(After generating the model, I modified the class names to match your naming convention.)
Given the correct data model, you can deserialize directly from a selected XmlNode using an XmlNodeReader as shown in How to deserialize a node in a large document using XmlSerializer without having to re-serialize to an intermediate XML string. The following extension method does the trick:
public static partial class XmlExtensions
{
public static IEnumerable<T> DeserializeElements<T>(this XmlNode root, string localName, string namespaceUri)
{
return new XmlNodeReader(root).DeserializeElements<T>(localName, namespaceUri);
}
public static IEnumerable<T> DeserializeElements<T>(this XmlReader reader, string localName, string namespaceUri)
{
var serializer = XmlSerializerFactory.Create(typeof(T), localName, namespaceUri);
while (!reader.EOF)
{
if (!(reader.NodeType == XmlNodeType.Element && reader.LocalName == localName && reader.NamespaceURI == namespaceUri))
reader.ReadToFollowing(localName, namespaceUri);
if (!reader.EOF)
{
yield return (T)serializer.Deserialize(reader);
// Note that the serializer will advance the reader past the end of the node
}
}
}
}
public static class XmlSerializerFactory
{
// To avoid a memory leak the serializer must be cached.
// https://stackoverflow.com/questions/23897145/memory-leak-using-streamreader-and-xmlserializer
// This factory taken from
// https://stackoverflow.com/questions/34128757/wrap-properties-with-cdata-section-xml-serialization-c-sharp/34138648#34138648
readonly static Dictionary<Tuple<Type, string, string>, XmlSerializer> cache;
readonly static object padlock;
static XmlSerializerFactory()
{
padlock = new object();
cache = new Dictionary<Tuple<Type, string, string>, XmlSerializer>();
}
public static XmlSerializer Create(Type serializedType, string rootName, string rootNamespace)
{
if (serializedType == null)
throw new ArgumentNullException();
if (rootName == null && rootNamespace == null)
return new XmlSerializer(serializedType);
lock (padlock)
{
XmlSerializer serializer;
var key = Tuple.Create(serializedType, rootName, rootNamespace);
if (!cache.TryGetValue(key, out serializer))
cache[key] = serializer = new XmlSerializer(serializedType, new XmlRootAttribute { ElementName = rootName, Namespace = rootNamespace });
return serializer;
}
}
}
Then you would deserialize as follows:
var modelData = doc.DeserializeElements<ReportXDto>("modelData", "").FirstOrDefault();
Working sample .Net fiddle here.
For Huge xml files always use XmlReader so you do not get an out of memory issue. See code below to get the element as a string :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
//or Create(Stream)
XmlReader reader = XmlReader.Create(FILENAME);
reader.ReadToFollowing("modelData");
if (!reader.EOF)
{
string modelDataStr = reader.ReadOuterXml();
}
}
}
}
I am facing a problem in deserializing xml into a class object. The class has a slightly different structure than the xml, so am unable to deserialize it. Following is the main code
public class Customer
{
[XmlElement(ElementName = "CustomerName")]
public string Name { get; set; }
}
public class XmlCheck
{
[XmlElement(ElementName = "Customer")]
public Customer Customer { get; set; }
public List<Customer> CustomersList { get; set; }
}
class Program
{
static string xml = #"<?xml version=""1.0"" ?>
<XmlCheck>
<Customer>
<CustomerName>Omer</CustomerName>
</Customer>
<Customer>
<CustomerName>Ali</CustomerName>
</Customer>
</XmlCheck>";
static void Main(string[] args)
{
var serializer = new XmlSerializer(typeof(XmlCheck), new XmlRootAttribute("XmlCheck"));
using (var stringReader = new StringReader(xml))
using (var reader = XmlReader.Create(stringReader))
{
var xmlResult = (XmlCheck)serializer.Deserialize(reader);
xmlResult.CustomersList.Add(xmlResult.Customer);
Console.WriteLine(xmlResult.Customer.Name);
}
}
Is there any way, to deserialize the xml into the customers list without having to insert that node inside the xml? Currently this only deserializes the first customer node that has name as 'Omer' and it adds that to the list.
I know how to accomplish the above by writing a custom xml reader, but need to use xml deserialization for this. However, if this isn't possible using xml deserialization, any way to achieve this using any customer (s/de)erializer?
Please try this:
public class Customer
{
[XmlElement(ElementName = "CustomerName")]
public string Name { get; set; }
}
[XmlRoot("XmlCheck")]
public class XmlCheck
{
[XmlElement(ElementName = "Customer")]
public List<Customer> CustomersList { get; set; }
}
class Program
{
static string xml = #"<?xml version=""1.0"" ?>
<XmlCheck>
<Customer>
<CustomerName>Omer</CustomerName>
</Customer>
<Customer>
<CustomerName>Ali</CustomerName>
</Customer>
</XmlCheck>";
static void Main(string[] args)
{
var serializer = new XmlSerializer(typeof(XmlCheck), new XmlRootAttribute("XmlCheck"));
using (var stringReader = new StringReader(xml))
using (var reader = XmlReader.Create(stringReader))
{
var xmlResult = (XmlCheck)serializer.Deserialize(reader);
//xmlResult.CustomersList.Add(xmlResult.Customer);
foreach(var c in xmlResult.CustomersList)
{
Console.WriteLine(c.Name);
}
}
}
}
I got it from: Is it possible to deserialize XML into List<T>?
I'm trying to convert the XML data to an object list, but it throws an error.
XML
<?xml version="1.0" encoding="utf-8" ?>
<Servers>
<Server>
<ServerName>STAGING</ServerName>
<ServerIP>XXX.XXX.XX.X</ServerIP>
</Server>
</Servers>
C#
public class ServerDetails
{
public string ServerName { get; set; }
public string ServerIP { get; set; }
}
private void GetXMLData()
{
XmlSerializer serializer = new XmlSerializer(typeof(List<ServerDetails>));
using (FileStream stream = File.OpenRead("D:\\Resource.xml"))
{
List<ServerDetails> list = (List<ServerDetails>)serializer.Deserialize(stream);
//Exception here
}
}
ERROR
Inner Exception : <Servers xmlns=''> was not expected.
There is an error in XML document (2,2)
I tried adding the [Serializabe] and [XMLElement] attributes to the class,
and also xmlns="http://www.example.com/xsd/ServerDetails" in the XML
but that did not help.
You have ServerDetails as your class name and in the xml the tag name is different, Try something like this.
public class ServerDetails
{
public string ServerName { get; set; }
public string ServerIP { get; set; }
}
public class ServerList
{
[XmlArray("Servers")]
[XmlArrayItem("Server", Type = typeof(ServerDetails))]
public ServerDetails[] Servers { get;set;}
}
private void GetXMLData()
{
XmlSerializer serializer = new XmlSerializer(typeof(ServerList));
using (FileStream stream = File.OpenRead("D:\\Resource.xml"))
{
var list = (ServerList)serializer.Deserialize(stream);
//Exception here
}
}
I used to use XmlSerializer a lot, but I totally stopped using it because you are forced to create your object structure fitting the xml structure. That makes it hard to maintain. Also XmlSerializer has some serious memory leaks.
If you don't mind, I would suggest to switch to XElement
public IEnumerable<ServerDetails> GetServers(string file)
{
using (var stream = File.Open(file, FileMode.Open, FileAccess.Read))
return GetServers(stream);
}
public IEnumerable<ServerDetails> GetServers(Stream stream)
{
var root = XElement.Load(stream);
return GetServers(root);
}
public IEnumerable<ServerDetails> GetServers(XElement root)
{
foreach (var server in root.Elements("Server"))
{
yield return new ServerDetails
{
ServerName = (string)server.Element("ServerName"),
ServerIP = (string)server.Element("ServerIP"),
};
}
}
Please note that you have to reference System.Xml.Linq
For your convenience here is a test case.
[TestMethod]
public void CanReadServers()
{
var xml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + #"
<Servers>
<Server>
<ServerName>STAGING</ServerName>
<ServerIP>XXX.XXX.XX.X</ServerIP>
</Server>
</Servers>";
IEnumerable<ServerDetails> servers;
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
servers = GetServers(stream).ToList();
Assert.AreEqual(1, servers.Count());
Assert.AreEqual("STAGING", servers.ElementAt(0).ServerName);
Assert.AreEqual("XXX.XXX.XX.X", servers.ElementAt(0).ServerIP);
}
Use XmlElement Notation to specify the element name.
public class Servers
{
[XmlElement("Server")]
public ServerDetails[] ServersDetails { get; set; }
}
public class ServerDetails
{
public string ServerName { get; set; }
public string ServerIP { get; set; }
}
private void GetXMLData()
{
XmlSerializer serializer = new XmlSerializer(typeof(Servers));
using (FileStream stream = File.OpenRead("D:\\Resource.xml"))
{
Servers list = (Servers)serializer.Deserialize(stream);
//Exception here
}
}
I have the follow XML structure:
<Document>
<Sectors>
<Sector>
SectorName1
<Subsectors>
<Subsector>Subsector1</Subsector>
<Subsector>Subsector2</Subsector>
</Subsectors>
</Sector>
<Sector>
SectorName2
<Subsectors>
<Subsector>Subsector1</Subsector>
<Subsector>Subsector2</Subsector>
</Subsectors>
</Sector>
</Sectors>
</Document>
Also I have classes for deserialize:
public class MetaDataXML
{
public class SectorXML
{
[XmlArrayItem(ElementName = "Sector")]
string SectorName { get; set; }
[XmlArray]
[XmlArrayItem(ElementName = "Subsector")]
public List<string> Subsectors { get; set; }
}
public List<SectorXML> Sectors { get; set; }
}
And part of code which do deserialize:
var xRoot = new XmlRootAttribute { ElementName = "Document", IsNullable = true };
var reader = new XmlSerializer(typeof(MetaDataXML), xRoot);
var data = (MetaDataXML)reader.Deserialize(streamXML);
After deserialization I successfully get subsectors velues, but I didn't get values for SectorName. How I need to organize my structure of class that I'll get values "SectorName1" and "SectorName2" for my string SectorName property?
I found that that this case it's a "Mixed Content". How we can parse this text values?
Whilst I am not entirely sure what it is you're trying to achieve here, I've made a few modifications to your XML class and provided some sample code below that is able to retrieve all of the information about a sector, including its name and the name of all the subsectors inside it.
XML Class:
namespace DocumentXml
{
[XmlRoot("Document")]
public class Document
{
[XmlArray("Sectors")]
[XmlArrayItem("Sector")]
public Sector[] Sectors { get; set; }
}
[XmlRoot("Sector")]
public class Sector
{
[XmlAttribute("SectorName")]
public string SectorName { get; set; }
[XmlArray("Subsectors")]
[XmlArrayItem("Subsector")]
public string[] Subsectors { get; set; }
}
}
Main Program Class:
namespace DocumentXml
{
class Program
{
static void Main(string[] args)
{
var path = #"D:\sandbox\DocumentXml\DocumentXml\Sample.xml";
var serializer = new XmlSerializer(typeof(Document));
var document = serializer.Deserialize(File.OpenRead(path)) as Document;
var sectors = document.Sectors;
foreach (var s in sectors)
{
Console.WriteLine($"Sector Name: {s.SectorName}");
foreach (var ss in s.Subsectors)
{
Console.WriteLine($"Subsector Name: {ss}");
}
Console.WriteLine();
}
Console.ReadKey();
}
}
}
Sample XML:
<Document>
<Sectors>
<Sector SectorName="SectorName1">
<Subsectors>
<Subsector>Subsector1</Subsector>
<Subsector>Subsector2</Subsector>
</Subsectors>
</Sector>
<Sector SectorName="SectorName2">
<Subsectors>
<Subsector>Subsector1</Subsector>
<Subsector>Subsector2</Subsector>
</Subsectors>
</Sector>
</Sectors>
</Document>
Output:
EDIT
Since the XML structure cannot be changed, this new class will preserve the structure and also allow you to get the value in question. XmlText returns everything inside the value so a custom set had to be used to ensure that the whitespace was correctly trimmed from it.
[XmlRoot("Document")]
public class MetaDataXml
{
[XmlArray("Sectors")]
[XmlArrayItem("Sector")]
public Sector[] Sectors { get; set; }
}
[XmlRoot("Sector")]
public class Sector
{
[XmlIgnore]
private string _sectorName;
[XmlText]
public string SectorName
{
get
{
return _sectorName;
}
set
{
_sectorName = value.Trim();
}
}
[XmlArray]
[XmlArrayItem(ElementName = "Subsector")]
public List<string> Subsectors { get; set; }
}
Sample Program:
class Program
{
static void Main(string[] args)
{
var path = #"D:\sandbox\DocumentXml\DocumentXml\Sample.xml";
using (var stream = File.OpenRead(path))
{
var deserializer = new XmlSerializer(typeof(MetaDataXml));
var data = (MetaDataXml)deserializer.Deserialize(stream);
foreach (var s in data.Sectors)
{
Console.WriteLine($"Sector Name: {s.SectorName}");
foreach (var ss in s.Subsectors)
{
Console.WriteLine($"Subsector Name: {ss}");
}
Console.WriteLine();
}
}
Console.ReadKey();
}
}
I have this existing XML file serving as a template with NO data, just simple nodes... here's a sample:
<?xml version="1.0" encoding="utf-8" ?>
<catalog>
<cd>
<title />
<artist />
<country />
<company />
<price />
<year />
</cd>
</catalog>
Now I have created a similar class for it.
public class Cd
{
public string Title { get; set; }
public string Artist { get; set; }
public string Country { get; set; }
public string Company { get; set; }
public string Price { get; set; }
public string Year { get; set; }
}
The purpose is this:
Put values on the properties of the var cd = new Cd(); object
Get the existing XML file (template) then pass the values in it (like mapping the object to the existing XML)
Transform the XML template(with values) into XSLT to become HTML
I think that's all.
How to properly do this?
Thanks a lot!
You can use serialization to achieve (1) and (2)
[Serializable]
public class Cd
{
public string Title { get; set; }
public string Artist { get; set; }
public string Country { get; set; }
public string Company { get; set; }
public string Price { get; set; }
public string Year { get; set; }
}
now in order to create an xml from an object use:
public static string SerializeObject<T>(this T obj)
{
var ms = new MemoryStream();
var xs = new XmlSerializer(obj.GetType());
var xmlTextWriter = new XmlTextWriter(ms, Encoding.UTF8);
xs.Serialize(xmlTextWriter, obj);
string serializedObject = new UTF8Encoding().GetString((((MemoryStream)xmlTextWriter.BaseStream).ToArray()));
return serializedObject;
}
in order to create an object from XML use:
public static T DeserializeObject<T>(this string xml)
{
if (xml == null)
throw new ArgumentNullException("xml");
var xs = new XmlSerializer(typeof(T));
var ms = new MemoryStream(new UTF8Encoding().GetBytes(xml));
try
{
new XmlTextWriter(ms, Encoding.UTF8);
return (T)xs.Deserialize(ms);
}
catch
{
return default(T);
}
finally
{
ms.Close();
}
}
I would create class:
class catalog
{
public CD cd {get;set;}
}
Here is serialization and deserealization helper:
public class Xml
{
public static string Serialize<T>(T value) where T : class
{
if (value == null)
{
return string.Empty;
}
var xmlSerializer = new XmlSerializer(typeof(T));
var stringWriter = new StringWriter();
using (var xmlWriter = XmlWriter.Create(stringWriter))
{
xmlSerializer.Serialize(xmlWriter, value);
return stringWriter.ToString();
}
}
public static T Deserialize<T>(string xml)
{
var serializer = new XmlSerializer(typeof(T));
T result;
using (TextReader reader = new StringReader(xml))
{
result = (T) serializer.Deserialize(reader);
}
return result;
}
}
Simply call:
catalog catalogObject = Xml.Deserialize<catalog>(xmlCatalogString);
I suspect you also will need to put some attributes on properties like XmlElement(ElementName = "title") because it is case sensitive.
MSDN