【问题标题】:Serializing a list of strongly typed objects序列化强类型对象列表
【发布时间】:2009-03-20 20:38:09
【问题描述】:

我可能搞砸了设计决策。我没有使用强类型的自定义对象集合,而是使用了通用列表。本质上,我所拥有的是:

public class AreaFields
{
    [XmlArray("Items")]
    [XmlArrayItem("Item")]
    public List<Fields> Fields { set; get; }

    [XmlAttribute]
    int id { set; get; }
}

public class Fields
{
    [XmlAttribute]
    public string Name { set; get; }
}

在整个应用程序中,我使用了List&lt;AreaFields&gt; 现在,我需要将列表序列化为 XML。我希望得到的是:

   <SomeXMLTag>
    <AreaFields id='1000'>
     <Items>
       <Item Name="Test1" />
       <Item Name="Test2" />
     </Items>
    </AreaFields>
    <AreaFields id='1001'>
     <Items>
       <Item Name="Test1" />
       <Item Name="Test2" />
     </Items>
    </AreaFields>
    </SomeXMLTag>

由于我无法序列化列表(或者我可以吗?),我将不得不序列化列表中的每个项目。

Ex: List<AreaFields> list = new List<AreaFields>();
//    more code to add to list
    list[0].GetRawXML(); //A method i have to serialize

【问题讨论】:

    标签: c# asp.net xml


    【解决方案1】:

    你需要一个包装类;然后按照您的示例序列化MyWrapper 的实例以获取xml。

    [XmlRoot("SomeXMLTag")]
    public class MyWrapper
    {
        [XmlElement("AreaFields")]
        public List<AreaFields> AreaFields { get; set; }
    }
    
    public class AreaFields
    {
        [XmlArray("Items")]
        [XmlArrayItem("Item")]
        public List<Fields> Fields { set; get; }
    
        [XmlAttribute]
        public int id { set; get; }
    }
    
    public class Fields
    {
        [XmlAttribute]
        public string Name { set; get; }
    }
    

    【讨论】:

      【解决方案2】:

      你可以序列化列表。阅读here 了解我使用的属性。

      【讨论】:

      • 我也序列化了通用列表
      【解决方案3】:
      using System;
      using System.Collections.Generic;
      using System.Xml;
      using System.Xml.Serialization;
      using System.Text;
      using System.IO;
      
      namespace Utils
      {
          public class XMLSerializer
          {
              public static Byte[] StringToUTF8ByteArray(String xmlString)
              {
                  return new UTF8Encoding().GetBytes(xmlString);
              }
      
              public static String SerializeToXML<T>(T objectToSerialize)
              {
                  StringBuilder sb = new StringBuilder();
      
                  XmlWriterSettings settings = 
                      new XmlWriterSettings {Encoding = Encoding.UTF8, Indent = true};
      
                  using (XmlWriter xmlWriter = XmlWriter.Create(sb, settings))
                  {
                      if (xmlWriter != null)
                      {
                          new XmlSerializer(typeof(T)).Serialize(xmlWriter, objectToSerialize);
                      }
                  }
      
                  return sb.ToString();
              }
      
              public static void DeserializeFromXML<T>(string xmlString, out T deserializedObject) where T : class
              {
                  XmlSerializer xs = new XmlSerializer(typeof (T));
      
                  using (MemoryStream memoryStream = new MemoryStream(StringToUTF8ByteArray(xmlString)))
                  {
                      deserializedObject = xs.Deserialize(memoryStream) as T;
                  }
              }
          }
      }
      

      然后,当您要打印列表时,请执行以下操作:

      List<AreaFields> list = new List<AreaFields>();
      //    more code to add to list
      Console.WriteLine(Utils.XMLSerializer.SerializeToXML(areaFields));
      

      编辑:更改序列化程序以避免其中一种二进制转换。你需要确保你想要序列化的所有属性都是公开的,并且你有一个不带参数的构造函数。

      【讨论】:

      • 您可以只使用 StringWriter 作为 XmlWriter 的源,然后调用 .ToString() - 更容易,并且没有二进制编码/解码来减慢速度。
      • 好点。此外,它应该在自己的命名空间中,以避免与 System.Xml.Serialization.XmlSerializer 冲突,当我将其从代码中拉出时忘记添加。
      【解决方案4】:

      Java 泛型通过类型擦除工作。这有点意味着当应用程序实际运行时,JVM 并不关心泛型。编译器会注意它们,然后将它们从字节码中丢弃(尽管某些注释放在 .class 文件等中)

      因此,对泛型类型的对象进行序列化和反序列化是一件轻而易举的事。它反序列化为一个列表,然后你将其转换。

      【讨论】:

        猜你喜欢
        • 2014-01-06
        • 1970-01-01
        • 2016-05-15
        • 2012-06-07
        • 2012-01-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-26
        相关资源
        最近更新 更多