views:

155

answers:

5

I'm having issues trying to deserializing my xml string that was from a dataset..

Here is the XML layout..

<DataSet>
  <User>
    <UserName>Test</UserName>
    <Email>[email protected]</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 am able to deserialize the "UserName" and "Email" when doing

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 Details isnt null but has no items in it..

i know I am suppose to have between all the details but I rather not modify the XML, anyways to get this to deserialize properly without recreating the XML after I get it?

A: 

Use Linq To XML.. something like this

XElement xe = XDocument.Load("PATH_HERE").Root;
 var v = from k in xe.Descendants()
                    select new {
                        id = k.Element("id"),
                        data = k.Element("data")
                    };  
Rbacarin
+1  A: 

I assume you are trying to use XmlSerializer? If so, you just need to add the [XmlElement] attribute to the Details member. This might not seem intuitive, but this tells the serializer that you want to serialize/deserialize the array items as elements rather than an array with the items as child elements of the array.

Here is a quick example

public Test()
{
  string xml = @"<DataSet> 
                   <User> 
                     <UserName>Test</UserName> 
                       <Email>[email protected]</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; }
}
Chris Taylor
The `Serializable` attribute is not needed for XML serialization
Thomas Levesque
Yes.. exactly.. thanks, worked just like I needed it, what a pain lol, knew it had to be a tag just didnt see which one i needed to use
LeeHull
+1  A: 

Use the XmlElement attribute on the Details property :

public class User
{
    public string UserName {get;set;}
    public string Email {get;set;}
    [XmlElement]
    public Details[] Details {get;set;}
}

If you don't, the XmlSerializer assumes that your <Details> elements are wrapped in a parent <Details> element

Thomas Levesque
A: 

Here's a sample program which makes no changes to the XML but deserializes the Details node properly:

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>[email protected]</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();
        }
    }
}
code4life
A: 

Hi

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>[email protected]</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;
    }
}
Vagaus