2

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?

5
  • Tried adding [XmlArrayItem(NestingLevel = 1, Type = typeof(Details))] above the property, but causes the Details to be null Commented May 18, 2010 at 17:47
  • 1
    Is your XML exactly as you have pasted? If so, it's malformed...missing the ending > after /Details Commented May 18, 2010 at 17:51
  • As mentioned above, you should mark your classes up with the attributes from the System.Xml.Serialization namespace when using Xml serialization. Commented May 18, 2010 at 17:52
  • oops.. no the XML is just a sample of my XML.. it has the end tag, was a misspelling on my part on posting here Commented May 18, 2010 at 17:58
  • The XML works fine, just doesnt deserialize Details array since it does not contain ArrayOfDetails, but i cant modify the XML, so cant figure out how to work around it... Commented May 18, 2010 at 18:01

5 Answers 5

4

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; }
}
Sign up to request clarification or add additional context in comments.

2 Comments

The Serializable attribute is not needed for XML serialization
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
1

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

Comments

0

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

Comments

0

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

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.