使用相同属性的变体序列化对象

时间:2013-03-09 13:23:57

标签: c# xml serialization

我有一个可以序列化对象的方法。

例如。

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>

如何调整我的代码以实现上述结果?

1 个答案:

答案 0 :(得分: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>();
    }
}

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

祝你好运

<强>奖金

将字符串解除分类到您的类型的扩展名:

/// <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>()