【问题标题】:Having issue Deserializing array from an XML string从 XML 字符串反序列化数组时遇到问题
【发布时间】:2010-05-18 17:45:44
【问题描述】:

我在尝试反序列化来自数据集的 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>

现在我可以在执行操作时反序列化“用户名”和“电子邮件”

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

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

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

【问题讨论】:

  • 尝试在属性上方添加 [XmlArrayItem(NestingLevel = 1, Type = typeof(Details))],但导致 Details 为空
  • 您的 XML 是否与您粘贴的完全相同?如果是这样,它的格式不正确...在 /Details 之后缺少结尾 >
  • 如上所述,在使用 Xml 序列化时,您应该使用 System.Xml.Serialization 命名空间中的属性标记您的类。
  • oops.. 不,XML 只是我的 XML 的一个示例。它有结束标记,是我在这里发帖时拼写错误
  • XML 工作正常,只是不反序列化 Details 数组,因为它不包含 ArrayOfDetails,但我无法修改 XML,所以无法弄清楚如何解决它...

标签: c# .net xml serialization


【解决方案1】:

我假设您正在尝试使用 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; }
}

【讨论】:

  • XML 序列化不需要Serializable 属性
  • 是的..正是..谢谢,就像我需要它一样工作,真痛苦哈哈,知道它必须是一个标签,只是没有看到我需要使用哪个
【解决方案2】:

Details 属性上使用XmlElement 属性:

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

如果您不这样做,XmlSerializer 会假定您的 &lt;Details&gt; 元素包含在父 &lt;Details&gt; 元素中

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      这是一个示例程序,它不对 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();
              }
          }
      }
      

      【讨论】:

        【解决方案5】:

        您需要执行以下操作:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-01-16
          • 2017-09-25
          • 1970-01-01
          • 2023-03-20
          • 1970-01-01
          相关资源
          最近更新 更多