Convert xml to List by Deserialize in c# - c#

i have a xml file and i am trying to populate my list with the data through deserialization.
my xml is here
<?xml version="1.0" ?>
<CustomerQueryRs>
<CustomerRet>
<ListID>6BE0000-1159990808</ListID>
<Name>+ Blaine Bailey</Name>
<FullName>+ Blaine Bailey</FullName>
<Phone>866-855-0800</Phone>
</CustomerRet>
<CustomerRet>
<ListID>9BA0000-1165353294</ListID>
<Name>+ Brian Boyd</Name>
<FullName>+ Brian Boyd</FullName>
<Phone>203-245-1877</Phone>
</CustomerRet>
<CustomerRet>
<ListID>9280000-1164147562</ListID>
<Name>+ Brian Leahy</Name>
<FullName>+ Brian Leahy</FullName>
<Phone>508-341-0955</Phone>
</CustomerRet>
</CustomerQueryRs>
here i am giving my full code. i just do not understand why my code is not working...what is missing in my code......it is not giving error but list is not getting populated. so please tell me which area i need to rectify in code.
[XmlTypeAttribute(AnonymousType = true)]
public class CustomersData
{
[XmlArray(ElementName = "CustomerQueryRs")]
[XmlArrayItem(ElementName = "CustomerRet")]
public List<Customer> Customers { get; set; }
public CustomersData()
{
Customers = new List<Customer>();
}
}
public class Customer
{
[XmlElement(ElementName = "ListID")]
public string ListID { get; set; }
[XmlElement(ElementName = "Name")]
public string Name { get; set; }
[XmlElement(ElementName = "FullName")]
public string FullName { get; set; }
[XmlElement(ElementName = "Phone")]
public string Phone { get; set; }
}
here is my desirialization code
private object DeserialzeXml(string xml)
{
var xmlSer = new XmlSerializer(typeof(CustomersData), new XmlRootAttribute("CustomerQueryRs"));
var stringReader = new StringReader(xml);
return xmlSer.Deserialize(stringReader);
}
please help......

This should work:
[XmlElement("CustomerRet")]
public List<Customer> Customers { get; set; }
And a full example:
[XmlTypeAttribute(AnonymousType = true)]
public class CustomersData
{
[XmlElement("CustomerRet")]
public List<Customer> Customers { get; set; }
public CustomersData()
{
Customers = new List<Customer>();
}
}
public class Customer
{
[XmlElement(ElementName = "ListID")]
public string ListID { get; set; }
[XmlElement(ElementName = "Name")]
public string Name { get; set; }
[XmlElement(ElementName = "FullName")]
public string FullName { get; set; }
[XmlElement(ElementName = "Phone")]
public string Phone { get; set; }
}
class Program
{
static void Main()
{
var xml =
#"<?xml version=""1.0"" ?>
<CustomerQueryRs>
<CustomerRet>
<ListID>6BE0000-1159990808</ListID>
<Name>+ Blaine Bailey</Name>
<FullName>+ Blaine Bailey</FullName>
<Phone>866-855-0800</Phone>
</CustomerRet>
<CustomerRet>
<ListID>9BA0000-1165353294</ListID>
<Name>+ Brian Boyd</Name>
<FullName>+ Brian Boyd</FullName>
<Phone>203-245-1877</Phone>
</CustomerRet>
<CustomerRet>
<ListID>9280000-1164147562</ListID>
<Name>+ Brian Leahy</Name>
<FullName>+ Brian Leahy</FullName>
<Phone>508-341-0955</Phone>
</CustomerRet>
</CustomerQueryRs>";
var serializer = new XmlSerializer(typeof(CustomersData), new XmlRootAttribute("CustomerQueryRs"));
using (var stringReader = new StringReader(xml))
using (var reader = XmlReader.Create(stringReader))
{
var result = (CustomersData)serializer.Deserialize(reader);
Console.WriteLine(result.Customers[1].FullName);
}
}
}

An Readable code for converting xml to list
string xmlString = System.IO.File.ReadAllText(#"C:\Users\user\Downloads\userDetail.xml");
List<GridViewDetails> userDetail = (List<GridViewDetails>)ConvertXmlStringtoObject<List<GridViewDetails>>(xmlString);
static T ConvertXmlStringtoObject<T>(string xmlString)
{
T classObject;
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
using (StringReader stringReader = new StringReader(xmlString))
{
classObject = (T)xmlSerializer.Deserialize(stringReader);
}
return classObject;
}

Related

Is there smart way to parse xml to list?

There is xml file, which have next structure:
<?xml version="1.0"?>
<myobjectlist objectCount = "3">
<myobject Number = "0" Name="My First Object" MyChildObectsCount = "2">
<intProp>5</intProp>
<stringProp>Str1</stringProp>
<doubleProp>35.1</doubleProp>
<MyChildObj Number = "100" Name = "My first child object">
<childIntProp>1</childIntProp>
<childStringProp>CStr1</childStringProp>
</MyChildObj>
<MyChildObj Number = "120" Name = "My child object">
<childIntProp>15</childIntProp>
<childStringProp>CStr2</childStringProp>
</MyChildObj>
</myobject>
<myobject Number = "145" Name="My second Object" MyChildObectsCount = "1">
<intProp>96</intProp>
<stringProp>Str2</stringProp>
<doubleProp>+Inf</doubleProp>
<MyChildObj Number = "250" Name = "This's child object">
<childIntProp>62</childIntProp>
<childStringProp>CStr3</childStringProp>
</MyChildObj>
</myobject>
<myobject Number = "261" Name="My last Object" MyChildObectsCount = "3">
<intProp>9</intProp>
<stringProp>Str45</stringProp>
<doubleProp>1.6449635e+07</doubleProp>
<MyChildObj Number = "150" Name = "Almost last child object">
<childIntProp>-1</childIntProp>
<childStringProp>CStr41</childStringProp>
</MyChildObj>
<MyChildObj Number = "680" Name = "Prelast child object">
<childIntProp>72</childIntProp>
<childStringProp>CStr42</childStringProp>
</MyChildObj>
<MyChildObj Number = "127" Name = "Last child object">
<childIntProp>64</childIntProp>
<childStringProp>CStr222</childStringProp>
</MyChildObj>
</myobject>
</myobjectlist>
I've tried to use XMLSerializer, but how I found out it can't deserialize to list, all objects of the list will be the first object of deserializable xml, so me result list will consist ObjCount of 0th obj.
I've created classes -- enteties of xml objects, let's say
public class MyObject{
int Number;
string Name;
int IntProp;
string stringProp;
double doubleProp;
List<MyChildObject> myChildObjects;
}
public class MyChildObject{
int Number;
string Name;
int childIntProp;
string childStringProp;
}
I need to get List<MyObject> from XML file, but I do not want to parse it node by node. Is there smart way to do it?
UPDATE
And here, what I got: Empty list
If you annotate your data model like this:
[XmlRoot(ElementName = "myobjectlist")]
public class MyObjectList
{
[XmlAttribute(AttributeName = "objectCount")]
public string ObjectCount { get; set; }
[XmlElement(ElementName = "myobject")]
public List<MyObject> MyObjects { get; set; }
}
[XmlRoot(ElementName = "myobject")]
public class MyObject
{
[XmlAttribute]
public string Number { get; set; }
[XmlAttribute]
public string Name { get; set; }
[XmlAttribute(AttributeName = "MyChildObectsCount")]
public string MyChildObjectsCount { get; set; }
[XmlElement(ElementName = "intProp")]
public string IntProp { get; set; }
[XmlElement(ElementName = "stringProp")]
public string StringProp { get; set; }
[XmlElement(ElementName = "doubleProp")]
public string DoubleProp { get; set; }
[XmlElement(ElementName = "MyChildObj")]
public List<MyChildObject> MyChildObjects { get; set; }
}
[XmlRoot(ElementName = "MyChildObj")]
public class MyChildObject
{
[XmlAttribute]
public string Number { get; set; }
[XmlAttribute]
public string Name { get; set; }
[XmlElement(ElementName = "childIntProp")]
public string ChildIntProp { get; set; }
[XmlElement(ElementName = "childStringProp")]
public string ChildStringProp { get; set; }
}
The the deseralization logic is this simple:
StreamReader reader = new StreamReader(File.OpenRead("sample.xml"));
var serializer = new XmlSerializer(typeof(MyObjectList));
var data = (MyObjectList)serializer.Deserialize(reader);
UPDATE #1
UPDATE #2
If you need to handle
+Inf as float.PositiveInfinity
-Inf as float.NegativeInfinity
then you need to change the text of the <doubleProp>. One way to do this is the following:
var malformedXml = File.ReadAllText("sample.xml");
var fixedXml = malformedXml
.Replace("<doubleProp>+Inf</doubleProp>", "<doubleProp>Infinity</doubleProp>")
.Replace("<doubleProp>-Inf</doubleProp>", "<doubleProp>-Infinity</doubleProp>");
var fixedXmlStream = new MemoryStream();
var writer = new StreamWriter(fixedXmlStream);
writer.Write(fixedXml);
writer.Flush();
fixedXmlStream.Position = 0;
var reader = new StreamReader(fixedXmlStream);

How can I return xml without <string> element?

I am using XML serialization in my project. It's working good but I am facing two issues.
Formatting of nodes
Remove <string></string> from response
Sample object which I am trying to serialize is :
[XmlRoot("result")]
public class SwRequestListModel
{
public SwRequestListModel()
{
SwRequest = new List<SwRequestShortInfo>();
}
[XmlElement("api_version")]
public string ApiVersion { get; set; }
[XmlElement("sw_request")]
public List<SwRequestShortInfo> SwRequest { get; set; }
}
[XmlRoot(ElementName = "sw_request_short_info")]
public class SwRequestShortInfo
{
[XmlElement(ElementName = "sw_ref_number")]
public string SwRefNumber { get; set; }
[XmlElement(ElementName = "db_no")]
public string DbNo { get; set; }
[XmlElement(ElementName = "engine_manufacturing_no")]
public string EngineManufacturingNo { get; set; }
[XmlElement(ElementName = "engine_ref_type")]
public string EngineRefType { get; set; }
[XmlElement(ElementName = "raised_date")]
public string RaisedDate { get; set; }
[XmlElement(ElementName = "raised_by")]
public string RaisedBy { get; set; }
[XmlElement(ElementName = "status")]
public string Status { get; set; }
[XmlElement(ElementName = "approved_by")]
public string ApprovedBy { get; set; }
[XmlElement(ElementName = "system_type")]
public string SystemType { get; set; }
}
The code which I am using to serialize is :
public static string ToXml(SwRequestListModel obj)
{
XmlSerializer s = new XmlSerializer(obj.GetType());
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
XmlWriterSettings settings = new XmlWriterSettings
{
Indent = true,
OmitXmlDeclaration = true,
Encoding = Encoding.UTF8,
NewLineOnAttributes = true,
NamespaceHandling = NamespaceHandling.OmitDuplicates,
IndentChars = Environment.NewLine
};
using (var sww = new StringWriter())
{
using (XmlWriter writer = XmlWriter.Create(sww, settings))
{
s.Serialize(writer, obj, ns);
return sww.ToString();
}
}
}
Response is display like :
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/"><result> <api_version>1.0</api_version> <sw_request> <sw_ref_number>588</sw_ref_number> <db_no>99899</db_no> <engine_manufacturing_no>MF99899</engine_manufacturing_no> <engine_ref_type>X40B</engine_ref_type> <raised_date>22/06/2021</raised_date> <raised_by>Srusti.Thakkar#test.com</raised_by> <status>Requested</status> <approved_by /> <system_type>test</system_type> </sw_request> <sw_request> <sw_ref_number>589</sw_ref_number> <db_no>88552</db_no> <engine_manufacturing_no>MF99899</engine_manufacturing_no> <engine_ref_type>X40B</engine_ref_type> <raised_date>22/06/2021</raised_date> <raised_by>Srusti.Thakkar#test.com</raised_by> <status>Requested</status> <approved_by /> <system_type>UNIC</system_type> </sw_request> <sw_request> <sw_ref_number>590</sw_ref_number> <db_no>33899</db_no> <engine_manufacturing_no>MF99899</engine_manufacturing_no> <engine_ref_type>X40B</engine_ref_type> <raised_date>22/06/2021</raised_date> <raised_by>Srusti.Thakkar#test.com</raised_by> <status>Requested</status> <approved_by /> <system_type>UNIC</system_type> </sw_request> </result></string>
Actual API Method is :
[HttpGet]
public string GetRequestList(string date, string status, string systemType)
{
SwRequestListModel result = new SwRequestListModel();
result.ApiVersion = "1.0";
//Here get data
return result.ToXml();
}
Browser result is :
Update :
I guess API method GetRequestList serialize string object. Try to return raw string.
[HttpGet]
public HttpResponseMessage GetRequestList(string date, string status, string systemType)
{
SwRequestListModel result = new SwRequestListModel();
result.ApiVersion = "1.0";
//Here get data
var response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent(result.ToXml());
return response;
}

Create a DataGridView out of a Xml File while using certain Elements as ColumnHeader

I currently have a XmlFile which look like the following (Note: the structure of this xmlFile is final) :
<Language>
<FileInfo NumberOfEntries="10" FileCreationTime="2017-07-14 12:23:07" />
<Entry Key="ABC_DEF_GHI" CreationTime="01.01.0001 00:00:00" LastModifiedTime="01.01.0001 00:00:00">
<LanguageEntry>
<ID>1</ID>
<Value>Hallo</Value>
<Comment>
</Comment>
<Mark>
</Mark>
</LanguageEntry>
<LanguageEntry>
<ID>2</ID>
<Value>Hello</Value>
<Comment>
</Comment>
<Mark>
</Mark>
</LanguageEntry>
...
</Entry>
...
</Language>
For now the only thing that matters are the Keys, which are given to one Entry, the ID and the Value.
I want to create a DataGridView which looks like the following:
Key | 1 | 2 | ID3 |...
---------------------------------------------
ABC_DEF_GHI|Hallo |Hello |someValue|...
---------------------------------------------
XYZ_DAF_ABC|someValue|someValue|someValue|...
. . . .
. . . .
. . . .
How can I achieve it, to make my DataGridView look like the one i showed above?
I tried using standard DataSet implementations, but I just can not think of a way of doing it. Please leave a comment, if you need any further information on what i try to get to or if something is unclear.
Thanks in advance!
First, you need to deserialize your data. In order to achive this you should have these classes.
[XmlRoot(ElementName = "FileInfo")]
public class FileInfo
{
[XmlAttribute(AttributeName = "NumberOfEntries")]
public string NumberOfEntries { get; set; }
[XmlAttribute(AttributeName = "FileCreationTime")]
public string FileCreationTime { get; set; }
}
[XmlRoot(ElementName = "LanguageEntry")]
public class LanguageEntry
{
[XmlElement(ElementName = "ID")]
public string ID { get; set; }
[XmlElement(ElementName = "Value")]
public string Value { get; set; }
[XmlElement(ElementName = "Comment")]
public string Comment { get; set; }
[XmlElement(ElementName = "Mark")]
public string Mark { get; set; }
}
[XmlRoot(ElementName = "Entry")]
public class Entry
{
[XmlElement(ElementName = "LanguageEntry")]
public List<LanguageEntry> LanguageEntry { get; set; }
[XmlAttribute(AttributeName = "Key")]
public string Key { get; set; }
[XmlAttribute(AttributeName = "CreationTime")]
public string CreationTime { get; set; }
[XmlAttribute(AttributeName = "LastModifiedTime")]
public string LastModifiedTime { get; set; }
}
[XmlRoot(ElementName = "Language")]
public class Language
{
[XmlElement(ElementName = "FileInfo")]
public FileInfo FileInfo { get; set; }
[XmlElement(ElementName = "Entry")]
public Entry Entry { get; set; }
}
And then you have to generate dynamic columns according to your data:
private void GenerateColumnsAndData(Language language)
{
var countIds = language.Entry.LanguageEntry.Count;
dataGridView1.ColumnCount = countIds + 1;
dataGridView1.Columns[0].Name = "Key";
for (int i = 0; i < language.Entry.LanguageEntry.Count; i++)
{
dataGridView1.Columns[i+1].Name = language.Entry.LanguageEntry[i].ID;
}
ArrayList row = new ArrayList();
row.Add(language.Entry.Key);
foreach (var item in language.Entry.LanguageEntry)
{
row.Add(item.Value);
}
dataGridView1.Rows.Add(row.ToArray());
}
Finally here's an example:
private void Form1_Load(object sender, EventArgs e)
{
string xml = #"<Language>
<FileInfo NumberOfEntries=""10"" FileCreationTime=""2017-07-14 12:23:07"" />
<Entry Key=""ABC_DEF_GHI"" CreationTime=""01.01.0001 00:00:00"" LastModifiedTime=""01.01.0001 00:00:00"">
<LanguageEntry>
<ID>1</ID>
<Value>Hallo</Value>
<Comment>
</Comment>
<Mark>
</Mark>
</LanguageEntry>
<LanguageEntry>
<ID>2</ID>
<Value>Hello</Value>
<Comment>
</Comment>
<Mark>
</Mark>
</LanguageEntry>
</Entry>
</Language>";
XmlSerializer serializer = new XmlSerializer(typeof(Language));
using(TextReader reader = new StringReader(xml))
{
Language result = (Language)serializer.Deserialize(reader);
GenerateColumnsAndData(result);
}
}
or if you are reading from a file try this:
using (FileStream fileStream = new FileStream("MyFilePath", FileMode.Open))
{
Language result = (Language)serializer.Deserialize(fileStream);
GenerateColumnsAndData(result);
}

Prefixes and Namespaces with C# Objects

I am attempting to create a POST function that serialises C# class objects into XML.
The part I am having great difficulty with is adding namespace prefixes to the sub-root element's children, so in this instance, contact children only.
The only way I seem to be able to get the prefix onto the child elements of contactis to add them through SerializerNamespace class, however I can only get this to attach to the root element, CreateContact.
How can I achieve this?
XML Currently Produced:
<?xml version=\"1.0\"?>
<CreateContact xmlns:a="http://foo.co.uk/Contact" xmlns="http://foo.co.uk">
<a:contact>
<a:Email>stest#gmail.com</a:Email>
<a:FirstName>Simon</a:FirstName>
<a:LastName>Test</a:LastName>
<a:Phone>09088408501</a:Phone>
<a:Title>Mr</a:Title>
</a:contact>
</CreateContact>
Serialisation function:
public static void CreateContact(Contact contact)
{
string tmp = url;
string xml = "";
string result = "";
XmlDocument xd = new XmlDocument();
var cc = new CreateContact();
cc.contact = contact;
var xs = new XmlSerializer(cc.GetType());
XmlSerializerNamespaces xsn = new XmlSerializerNamespaces();
xsn.Add("a", "http://foo.co.uk/Contact");
using (MemoryStream ms = new MemoryStream())
{
xs.Serialize(ms, cc, xsn);
ms.Position = 0;
xd.Load(ms);
xml = xd.InnerXml;
}
using (WebClient web = new WebClient())
{
web.Credentials = new NetworkCredential(username, password);
web.Headers.Add("Content-Type", "application/xml");
try
{
result = web.UploadString(tmp, "POST", xml);
}
catch (WebException ex)
{
}
}
}
XML Class Constructs:
[Serializable()]
[XmlRoot(ElementName = "CreateContact", Namespace = "http://foo.co.uk")]
public class CreateContact
{
[XmlElement(ElementName = "contact", Namespace = "http://foo.co.uk/Contact")]
public Contact contact { get; set; }
}
[DataContract(Name = "Contact", Namespace = "http://foo.co.uk/Contact")]
[XmlType("a")]
public class Contact
{
[XmlElement(ElementName = "Email", Namespace = "http://foo.co.uk/Contact")]
[DataMember(Name = "Email")]
public string Email { get; set; }
[XmlElement(ElementName = "FirstName", Namespace = "http://foo.co.uk/Contact")]
[DataMember(Name = "FirstName")]
public string Firstname { get; set; }
[XmlElement(ElementName = "LastName", Namespace = "http://foo.co.uk/Contact")]
[DataMember(Name = "LastName")]
public string Lastname { get; set; }
[XmlElement(ElementName = "Phone", Namespace = "http://foo.co.uk/Contact")]
[DataMember(Name = "Phone")]
public string Phone { get; set; }
[XmlElement(ElementName = "Title", Namespace = "http://foo.co.uk/Contact")]
[DataMember(Name = "Title")]
public string Title { get; set; }
}
XML Desired:
<?xml version=\"1.0\"?>
<CreateContact xmlns="http://foo.co.uk">
<contact xmlns:a="http://foo.co.uk/Contact">
<a:Email>stest#gmail.com</a:Email>
<a:FirstName>Simon</a:FirstName>
<a:LastName>Test</a:LastName>
<a:Phone>09088408501</a:Phone>
<a:Title>Mr</a:Title>
</contact>
</CreateContact>
As alluded in the comments, the reason for the difference is that contact should be in the namespace http://foo.co.uk, not http://foo.co.uk/Contact.
As an aside, a couple of further comments:
You probably don't need the DataMember attributes, unless you're using DataContractSerializer somewhere else.
Most of the Xml* attributes are superfluous here, and could be removed or consolidated by inheriting from XmlRoot.
If all you need is the XML string, you'd be better off serialising to something like a StringWriter rather than to a stream and then loading into the DOM just to get the text (see this question if you need the XML declaration to specify utf-8)
So, you'd get the XML as below:
var xsn = new XmlSerializerNamespaces();
xsn.Add("a", "http://foo.co.uk/Contact");
var xs = new XmlSerializer(typeof(CreateContact));
using (var stringWriter = new StringWriter())
{
xs.Serialize(stringWriter, cc, xsn);
xml = stringWriter.ToString();
}
With your classes defined as:
[XmlRoot(ElementName = "CreateContact", Namespace = "http://foo.co.uk")]
public class CreateContact
{
[XmlElement(ElementName = "contact")]
public Contact Contact { get; set; }
}
[XmlRoot("contact", Namespace = "http://foo.co.uk/Contact")]
public class Contact
{
public string Email { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Phone { get; set; }
public string Title { get; set; }
}
See this fiddle for the complete example.

Problems deserializing List of objects

I am having trouble deserializing a list of objects. I can get just one object to serialize into an object but cannot get the list. I get no error it just returns an empty List. This is the XML that gets returned:
<locations>
<location locationtype="building" locationtypeid="1">
<id>1</id>
<name>Building Name</name>
<description>Description of Building</description>
</location>
</locations>
This is the class I have and I am deserializing in the GetAll method:
[Serializable()]
[XmlRoot("location")]
public class Building
{
private string method;
[XmlElement("id")]
public int LocationID { get; set; }
[XmlElement("name")]
public string Name { get; set; }
[XmlElement("description")]
public string Description { get; set; }
[XmlElement("mubuildingid")]
public string MUBuildingID { get; set; }
public List<Building> GetAll()
{
var listBuildings = new List<Building>();
var building = new Building();
var request = WebRequest.Create(method) as HttpWebRequest;
var response = request.GetResponse() as HttpWebResponse;
var streamReader = new StreamReader(response.GetResponseStream());
TextReader reader = streamReader;
var serializer = new XmlSerializer(typeof(List<Building>),
new XmlRootAttribute() { ElementName = "locations" });
listBuildings = (List<Building>)serializer.Deserialize(reader);
return listBuildings;
}
}
Try this:
[XmlRoot("locations")]
public class BuildingList
{
public BuildingList() {Items = new List<Building>();}
[XmlElement("location")]
public List<Building> Items {get;set;}
}
Then deserialize the whole BuildingList object.
var xmlSerializer = new XmlSerializer(typeof(BuildingList));
var list = (BuildingList)xmlSerializer.Deserialize(xml);
I know this is an old(er) question, but I struggled with this today, and found an answer that doesn't require encapsulation.
Assumption 1: You have control over the source Xml and how it is constructed.
Assumption 2: You are trying to serialise the Xml directly into a List<T> object
You must name the Root element in the Xml as ArrayOfxxx where xxx is the name of your class (or the name specified in XmlType (see 2.))
If you wish your xml Elements to have a different name to the class, you should use XmlType on the class.
NB: If your Type name (or class name) starts with a lowercase letter, you should convert the first character to uppercase.
Example 1 - Without XmlType
class Program
{
static void Main(string[] args)
{
//String containing the xml array of items.
string xml =
#"<ArrayOfItem>
<Item>
<Name>John Doe</Name>
</Item>
<Item>
<Name>Martha Stewart</Name>
</Item>
</ArrayOfItem>";
List<Item> items = null;
using (var mem = new MemoryStream(Encoding.Default.GetBytes(xml)))
using (var stream = new StreamReader(mem))
{
var ser = new XmlSerializer(typeof(List<Item>)); //Deserialising to List<Item>
items = (List<Item>)ser.Deserialize(stream);
}
if (items != null)
{
items.ForEach(I => Console.WriteLine(I.Name));
}
else
Console.WriteLine("No Items Deserialised");
}
}
public class Item
{
public string Name { get; set; }
}
Example 2 - With XmlType
class Program
{
static void Main(string[] args)
{
//String containing the xml array of items.
//Note the Array Name, and the Title case on stq.
string xml =
#"<ArrayOfStq>
<stq>
<Name>John Doe</Name>
</stq>
<stq>
<Name>Martha Stewart</Name>
</stq>
</ArrayOfStq>";
List<Item> items = null;
using (var mem = new MemoryStream(Encoding.Default.GetBytes(xml)))
using (var stream = new StreamReader(mem))
{
var ser = new XmlSerializer(typeof(List<Item>)); //Deserialising to List<Item>
items = (List<Item>)ser.Deserialize(stream);
}
if (items != null)
{
items.ForEach(I => Console.WriteLine(I.Name));
}
else
Console.WriteLine("No Items Deserialised");
}
}
[XmlType("stq")]
public class Item
{
public string Name { get; set; }
}
Not sure how Building corresponds with the location you have in your xml, but to me it makes more sense if they're named equivalently. Instead of using a List use a LocationList, and it becomes:
[Serializable()]
[XmlRoot("locations")]
public class LocationCollection{
[XmlElement("location")]
public Location[] Locations {get;set;}
}
[Serializable()]
[XmlRoot("location")]
public class Location
{
[XmlElement("id")]
public int LocationID { get; set; }
[XmlAttribute("locationtype")]
public string LocationType {get;set;}
[XmlElement("name")]
public string Name { get; set; }
[XmlElement("description")]
public string Description { get; set; }
[XmlElement("mubuildingid")]
public string MUBuildingID { get; set; }
}
You can then deserialize as follows:
var request = WebRequest.Create(method) as HttpWebRequest;
var response = request.GetResponse() as HttpWebResponse;
var streamReader = new StreamReader(response.GetResponseStream());
TextReader reader = streamReader;
var serializer = new XmlSerializer(typeof(LocationCollection),
new XmlRootAttribute() { ElementName = "locations" });
var listBuildings = (LocationCollection)serializer.Deserialize(reader);
return listBuildings;
I know, old question, but came across it when faced by a similar issue.
Building on #ricovox's answer and in context of the OP's question, this is the model I would use to serialize his xml:
[Serializable, XmlRoot("locations")]
public class BuildingList
{
[XmlArrayItem("location", typeof(Building))]
public List<Building> locations { get; set; }
}
[Serializable]
public class Building
{
public int LocationID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string MUBuildingID { get; set; }
public List<Building> GetAll()
{
...
}
}
The OP's mistake was to create the list item as the root
Use [XMLArray] for collection properties.

Categories