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?

+2


a source to share


5 answers


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; }
}

      

+3


a source


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>

+1


a source


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")
                    };  

      

0


a source


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();
        }
    }
}

      

0


a source


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;
    }
}

      

0


a source







All Articles