2013-03-09 66 views
0

我有一种方法可以序列化一个对象。例如序列化具有相同属性变体的对象

List<Titles> lstCrmTitleSer = new List<Titles>(); 

我循环访问字符串标题的集合,然后将它添加到类型标题的列表中以序列化它们。

foreach (var ls in lstCrmTitles) 
{ 
    Titles t = new Titles(); 

    t.title = ls; 
    lstCrmTitleSer.Add(t); 
} 

这是我的序列化对象的对象和方法。

static public void SerializeToXMLCollection(List<Titles> trainingTitles) 
{ 
    XmlSerializer serializer = new XmlSerializer(typeof(List<Titles>)); 
    string path = string.Concat(@"C:\Users\Arian\Desktop\Titles.xml"); 
    Console.WriteLine(path); 
    TextWriter textWriter = new StreamWriter(path); 
    serializer.Serialize(textWriter, trainingTitles); 
    textWriter.Close(); 
} 

public string title { get; set; } 

的事情是我的XML文件显示如下

<Titles> 
     <title>title a</title> 
</Titles> 
<Titles> 
     <title>title b</title> 
</Titles> 
<Titles> 
     <title>title c</title> 
</Titles> 

我想如果要显示我的XML作为跟随

<Titles> 
     <title>title a</title> 
     <title>title b</title> 
     <title>title c</title> 
</Titles> 

我如何调整我的代码为了达到上述目标?

+0

你可以切换到[LINQ到XML](http://msdn.microsoft.com/en-us/library/bb387098.aspx)。这会起作用吗? – Default 2013-03-09 13:29:17

+0

确实注意到你的建议意味着你不能反序列化它。这是你的问题吗? – Default 2013-03-09 14:15:22

+0

反序列化也是一样容易..我也有一个扩展,如果你想要它 – Matt 2013-03-09 14:27:13

回答

1

首先。这里有一个通用的扩展方法给你使用..我几年前写它,它会序列化任何东西:

/// <summary> 
/// <para>Serializes the specified System.Object and writes the XML document</para> 
/// <para>to the specified file.</para> 
/// </summary> 
/// <typeparam name="T">This item's type</typeparam> 
/// <param name="item">This item</param> 
/// <param name="fileName">The file to which you want to write.</param> 
/// <returns>true if successful, otherwise false.</returns> 
public static bool XmlSerialize<T>(this T item, string fileName) 
{ 
    return item.XmlSerialize(fileName, true); 
} 

/// <summary> 
/// <para>Serializes the specified System.Object and writes the XML document</para> 
/// <para>to the specified file.</para> 
/// </summary> 
/// <typeparam name="T">This item's type</typeparam> 
/// <param name="item">This item</param> 
/// <param name="fileName">The file to which you want to write.</param> 
/// <param name="removeNamespaces"> 
///  <para>Specify whether to remove xml namespaces.</para>para> 
///  <para>If your object has any XmlInclude attributes, then set this to false</para> 
/// </param> 
/// <returns>true if successful, otherwise false.</returns> 
public static bool XmlSerialize<T>(this T item, string fileName, bool removeNamespaces) 
{ 
    object locker = new object(); 

    XmlSerializerNamespaces xmlns = new XmlSerializerNamespaces(); 
    xmlns.Add(string.Empty, string.Empty); 

    XmlSerializer xmlSerializer = new XmlSerializer(typeof(T)); 

    XmlWriterSettings settings = new XmlWriterSettings(); 
    settings.Indent = true; 
    settings.OmitXmlDeclaration = true; 

    lock (locker) 
    { 
     using (XmlWriter writer = XmlWriter.Create(fileName, settings)) 
     { 
      if (removeNamespaces) 
      { 
       xmlSerializer.Serialize(writer, item, xmlns); 
      } 
      else { xmlSerializer.Serialize(writer, item); } 

      writer.Close(); 
     } 
    } 

    return true; 
} 

/// <summary> 
/// Serializes the specified System.Object and returns the serialized XML 
/// </summary> 
/// <typeparam name="T">This item's type</typeparam> 
/// <param name="item">This item</param> 
/// <param name="removeNamespaces"> 
///  <para>Specify whether to remove xml namespaces.</para>para> 
///  <para>If your object has any XmlInclude attributes, then set this to false</para> 
/// </param> 
/// <returns>Serialized XML for specified System.Object</returns> 
public static string XmlSerialize<T>(this T item, bool removeNamespaces = true) 
{ 
    object locker = new object(); 
    XmlSerializerNamespaces xmlns = new XmlSerializerNamespaces(); 
    xmlns.Add(string.Empty, string.Empty); 

    XmlSerializer xmlSerializer = new XmlSerializer(typeof(T)); 

    XmlWriterSettings settings = new XmlWriterSettings(); 
    settings.Indent = true; 
    settings.OmitXmlDeclaration = true; 

    lock (locker) 
    { 
     StringBuilder stringBuilder = new StringBuilder(); 
     using (StringWriter stringWriter = new StringWriter(stringBuilder)) 
     { 
      using (XmlWriter xmlWriter = XmlWriter.Create(stringWriter, settings)) 
      { 
       if (removeNamespaces) 
       { 
        xmlSerializer.Serialize(xmlWriter, item, xmlns); 
       } 
       else { xmlSerializer.Serialize(xmlWriter, item); } 

       return stringBuilder.ToString(); 
      } 
     } 
    } 
} 

其次。像这样使用它:

internal class Program 
{ 
    private static void Main(string[] args) 
    { 
     var list = new MyObject(); 
     list.Titles.Add("title1"); 
     list.Titles.Add("title2"); 
     list.Titles.Add("title3"); 

     string serialized = list.XmlSerialize(); 

     //obviously here you would save to disk or whatever 
     Console.WriteLine(serialized); 
     Console.ReadLine(); 
    } 
} 

[XmlRoot("Titles")] 
public class MyObject 
{ 
    [XmlElement("title")] 
    public List<string> Titles { get; set; } 

    public MyObject() 
    { 
     Titles = new List<string>(); 
    } 
} 

第三,..代码只是讨厌。即使有了上述建议,我仍然认为你需要做一些严肃的重构。

好运

BONUS

扩展deseralizing串到你的类型:

/// <summary> 
/// Deserializes the XML data contained by the specified System.String 
/// </summary> 
/// <typeparam name="T">The type of System.Object to be deserialized</typeparam> 
/// <param name="s">The System.String containing XML data</param> 
/// <returns>The System.Object being deserialized.</returns> 
public static T XmlDeserialize<T>(this string s) 
{ 
    if (string.IsNullOrEmpty(s)) 
    { 
     return default(T); 
    } 

    var locker = new object(); 
    var stringReader = new StringReader(s); 
    var reader = new XmlTextReader(stringReader); 
    try 
    { 
     var xmlSerializer = new XmlSerializer(typeof(T)); 
     lock (locker) 
     { 
      var item = (T)xmlSerializer.Deserialize(reader); 
      reader.Close(); 
      return item; 
     } 
    } 
    catch 
    { 
     return default(T); 
    } 
    finally 
    { 
     reader.Close(); 
    } 
} 

使用方法如下:

var myObject = someSerializedString.XmlDeserialize<MyObject>() 
+0

为什么他应该使用你的扩展方法?我没有看到利润。另外,OP似乎没有任何'MyObject'类。那个是从哪里来的?你的代码与OP有很大的不同。你能扩展什么“代码看起来讨厌”和OP可以做什么使它看起来不讨厌? – Default 2013-03-09 14:15:59

+0

我把它叫做MyObject,因为我不知道OP想要调用那个类。我试过标题,但编译器抛出一个错误,原因是你不能拥有和类本身一样的属性名称。我会把它交给OP,在他认为合适的时候改变。 – Matt 2013-03-09 14:21:37

+0

他不必使用我的扩展方法..但是它有什么问题?它可以为此工作,并且还可以为他节省下来的麻烦,即需要随时随地将它写入其他任何其他课程中,以便他将来可能要序列化的任何其他课程中。我多年来一直使用它,并且从不需要其他任何东西。你在做什么大惊小怪? – Matt 2013-03-09 14:23:19

相关问题