使用“\ n”反序列化字符串列表会导致空字符串

时间:2013-06-25 14:11:25

标签: c# xml xml-serialization newline xmlserializer

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

我有一个复杂的对象,其中包含一个字符串列表,需要序列化为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是包含字符串List的对象。字符串列表可以是可变长度,但样本数据可能看起来像这样......

[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”。也许这个问题太多了。

任何见解都会非常感激。感谢。

1 个答案:

答案 0 :(得分:2)

您需要使用XmlReaderXmlWriter课程或DataContractSerializer

请参阅:How to keep XmlSerializer from killing NewLines in Strings?

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");