0

我一直在努力解决这个问题。似乎它必须是一个简单的解决方案,但我已经搜索了互联网并尝试了很多东西。

我有一个复杂的对象,其中包含一个需要序列化为 xml 然后反序列化的字符串列表。

序列化代码早已成为应用程序的一部分并在无数其他场景中工作,但这里的问题似乎是字符串列表中的元素之一仅仅是换行符(即“\n”)。

这是我的理解,根据我的研究,它正在按预期进行序列化(见下文),但在反序列化之后,元素包含一个空字符串(即“”)而不是“\n”。

这是代码...

public DoStuff(ItemTypeObj item)
{
    string myItem = XmlSerialize<ItemType>(item);
    ItemTypeObj myNewItemTypeObj = XmlDeserialize<CustomItem>(myItem)
}

public static string XmlSerialize<T>(T objectToSerialize)
{
    string ret = string.Empty;

    XmlSerializer s = new XmlSerializer(typeof(T));
    using (MemoryStream ms = new MemoryStream())
    {
        s.Serialize(ms, objectToSerialize);
        ms.Position = 0;
        using (StreamReader sr = new StreamReader(ms))
        {
            sRet = sr.ReadToEnd();
        }
    }
    return ret;
}

public static T XmlDeserialize<T>(string serializedObject)
{
    T retVal = default(T);
    byte[] ba = ASCIIEncoding.UTF8.GetBytes(serializedObject);
    using (MemoryStream ms = new MemoryStream(ba))
    {
        XmlSerializer s = new XmlSerializer(typeof(T));

        retVal = (T)s.Deserialize(ms);               
    }
    return retVal;
}

为了让您了解发送的数据,ItemTypeObj 是包含字符串列表的对象。字符串列表可以是可变长度,但示例数据可能如下所示......

[0] = "Zero element text \n"
[1] = "[element1]"
[2] = "\n"
[3] = "[element3]"
[4] = "\n"
[5] = "[element5]"

序列化后它看起来像这样(这对我来说似乎是正确的):

  <Text>
    <string>Zero element text
</string>
    <string>[element1]</string>
    <string>
</string>
    <string>[element3]</string>
    <string>
</string>
    <string>[element5]</string>
 <Text>

从我读过的内容来看,换行符在上面的 xml 中按预期表示。问题是在它被反序列化之后,字符串列表是这样的:

[0] = "Zero element text \n"
[1] = "[element1]"
[2] = ""
[3] = "[element3]"
[4] = ""
[5] = "[element5]"

只有同时具有文本的元素中的换行符(例如 [0])仍然存在。其他两个替换为空字符串。如果我向这些元素添加文本,则将保留新行。

查看反序列化中的字节数组,序列化字符串中“\n”所在位置的数组元素变为10(又名LF,新行)。然后在反序列化中没有成功地变成“\n”。也许这问得太多了。

任何见解将不胜感激。谢谢。

4

1 回答 1

2

您需要使用XmlReaderandXmlWriter类或DataContractSerializer.

请参阅:如何防止 XmlSerializer 杀死字符串中的 NewLines?

public static string XmlSerialize<T>(T objectToSerialize)
{
    XmlSerializer s = new XmlSerializer(typeof(T));

    var settings = new XmlWriterSettings
                       {
                           NewLineHandling = NewLineHandling.Entitize
                       };

    using(var stream = new StringWriter())
    using(var writer = XmlWriter.Create(stream, settings))
    {
        s.Serialize(writer, objectToSerialize);

        return stream.ToString();
    }
}

public static T XmlDeserialize<T>(string serializedObject)
{
    XmlSerializer s = new XmlSerializer(typeof(T));

    using(var stream = new StringReader(serializedObject))
    using(var reader = XmlReader.Create(stream))
    {
        return (T)s.Deserialize(reader);
    }
}

用法:

public class Foo
{
    public string Bar { get; set; }
}

var foo = new Foo { Bar = "\n" };
var result = XmlSerialize(foo);

Console.WriteLine(result);

var newFoo = XmlDeserialize<Foo>(result);

Console.WriteLine(newFoo.Bar);
Debug.Assert(newFoo.Bar == "\n");
于 2013-06-25T14:51:03.187 回答