有问题从XML字符串反序列化数组

时间:2010-05-18 17:45:44

标签: c# .net xml serialization

我在尝试反序列化来自数据集的xml字符串时遇到问题。

这是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>

现在,我可以在执行

时反序列化“UserName”和“Email”
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;}
}

当我刚刚获得用户节点时,这反序列化很好,详细信息不是null但是没有项目..

我知道我想要介于所有细节之间,但我宁愿不修改XML,无论如何都要正确反序列化,而不是在我得到它之后重新创建XML?

5 个答案:

答案 0 :(得分:3)

我假设您正在尝试使用XmlSerializer?如果是这样,您只需要将[XmlElement]属性添加到Details成员。这可能看起来不太直观,但这告诉序列化程序您要将数组项序列化/反序列化为元素,而不是将项目作为数组子元素的数组。

这是一个简单的例子

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

答案 1 :(得分:1)

使用XmlElement媒体资源上的Details属性:

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

如果不这样做,XmlSerializer会假定您的<Details>元素包含在父<Details>元素中

答案 2 :(得分:0)

使用Linq To XML ..类似这样的

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

答案 3 :(得分:0)

这是一个示例程序,它不对XML进行任何更改,但正确地反序列化Details节点:

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

答案 4 :(得分:0)

您需要执行以下操作:

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