Issuing deserializing an array from an XML string
I am having trouble deserializing my xml string that was from a dataset.
Here is the XML layout.
<DataSet>
<User>
<UserName>Test</UserName>
<Email>test@test.com</Email>
<Details>
<ID>1</ID>
<Name>TestDetails</Name>
<Value>1</Value>
</Details>
<Details>
<ID>2</ID>
<Name>Testing</Name>
<Value>3</Value>
</Details>
</User>
</DataSet>
Now I can deserialize "UserName" and "Email" when running
public class User
{
public string UserName {get;set;}
public string Email {get;set;}
public Details[] Details {get;set;}
}
public class Details
{
public int ID {get;set;}
public string Name {get;set;}
public string Value {get;set;}
}
This deserializes fine, when I just get the user node, the information isnt null, but there are no items in it.
I know I have to have in between all the details, but I am rather not modifying the XML anyway to get this to deserialize correctly without recreating the XML after I get it?
a source to share
I am assuming you are trying to use the XmlSerializer? If so, you just need to add an attribute [XmlElement]
to the Details element. This may sound unintuitive, but it tells the serializer that you want to serialize / deserialize the elements of the array as elements , not an array with the elements as children of the array.
Here's a quick example
public Test()
{
string xml = @"<DataSet>
<User>
<UserName>Test</UserName>
<Email>test@test.com</Email>
<Details>
<ID>1</ID>
<Name>TestDetails</Name>
<Value>1</Value>
</Details>
<Details>
<ID>2</ID>
<Name>Testing</Name>
<Value>3</Value>
</Details>
</User>
</DataSet>";
XmlSerializer xs = new XmlSerializer(typeof(DataSet));
DataSet ds = (DataSet)xs.Deserialize(new StringReader(xml));
}
[Serializable]
public class DataSet
{
public User User;
}
[Serializable]
public class User
{
public string UserName { get; set; }
public string Email { get; set; }
[XmlElement]
public Details[] Details { get; set; }
}
[Serializable]
public class Details
{
public int ID { get; set; }
public string Name { get; set; }
public string Value { get; set; }
}
a source to share
Use the attribute XmlElement
on the property Details
:
public class User
{
public string UserName {get;set;}
public string Email {get;set;}
[XmlElement]
public Details[] Details {get;set;}
}
If you don't, XmlSerializer
assumes your elements are <Details>
wrapped in their parent<Details>
a source to share
Here's a sample program that doesn't make any changes to the XML, but deserializes the Details node correctly:
using System;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
using System.IO;
using System.Diagnostics;
using System.Collections.Generic;
namespace ConsoleApplication1
{
[System.Xml.Serialization.XmlRootAttribute(Namespace = "",
IsNullable = false)]
public class DataSet
{
public User User { get; set; }
}
public class User
{
public string UserName { get; set; }
public string Email { get; set; }
[System.Xml.Serialization.XmlElementAttribute("Details")]
public Details[] Details { get; set; }
}
public class Details
{
public int ID { get; set; }
public string Name { get; set; }
public string Value { get; set; }
}
class Program
{
static void Main(string[] args)
{
string xmlFragment =
@"<DataSet>
<User>
<UserName>Test</UserName>
<Email>test@test.com</Email>
<Details>
<ID>1</ID>
<Name>TestDetails</Name>
<Value>1</Value>
</Details>
<Details>
<ID>2</ID>
<Name>Testing</Name>
<Value>3</Value>
</Details>
</User>
</DataSet>";
StringReader reader = new StringReader(xmlFragment);
XmlSerializer xs = new XmlSerializer(typeof(DataSet));
DataSet ds = xs.Deserialize(reader) as DataSet;
User user = ds.User;
Console.WriteLine("User name: {0}", user.UserName);
Console.WriteLine("Email: {0}", user.Email);
foreach (Details detail in user.Details)
{
Console.WriteLine("Detail [ID]: {0}", detail.ID);
Console.WriteLine("Detail [Name]: {0}", detail.Name);
Console.WriteLine("Detail [Value]: {0}", detail.Value);
}
// pause program execution to review results...
Console.WriteLine("Press enter to exit");
Console.ReadLine();
}
}
}
a source to share
You need to do something like:
using System.IO;
using System.Xml.Serialization;
namespace TestSerialization
{
class Program
{
static void Main(string[] args)
{
string content= @"<DataSet>
<User>
<UserName>Test</UserName>
<Email>test@test.com</Email>
<Details>
<Detail>
<ID>1</ID>
<Name>TestDetails</Name>
<Value>1</Value>
</Detail>
<Detail>
<ID>2</ID>
<Name>Testing</Name>
<Value>3</Value>
</Detail>
</Details>
</User>
</DataSet>";
XmlSerializer serializaer = new XmlSerializer(typeof(DataSet));
DataSet o = (DataSet) serializaer.Deserialize(new StringReader(content));
}
}
public class User
{
public string UserName { get; set; }
public string Email { get; set; }
public Detail[] Details { get; set; }
}
public class Detail
{
public int ID { get; set; }
public string Name { get; set; }
public string Value { get; set; }
}
public class DataSet
{
public User User;
}
}
a source to share