【问题标题】:Deserializing string list with "\n" results in empty string使用“\n”反序列化字符串列表会导致空字符串
【发布时间】:2013-06-25 14:11:24
【问题描述】:

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

我有一个复杂的对象,其中包含一个需要序列化为 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”。或许这个要求太高了。

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

【问题讨论】:

    标签: c# xml xml-serialization newline xmlserializer


    【解决方案1】:

    您需要使用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");
    

    【讨论】:

    • 谢谢。尽管 xml 字符串未格式化,但这似乎确实有效。谁能解释为什么原始代码仅在列表元素中的 only 事物时才删除新行?这就是为什么我看到的您的链接似乎不适用于我的原因。
    • 序列化程序删除换行符,因为它认为它不是数据。
    • @Romuku - 这并不是我评论中问题的真正解释。 :) 此外,只有我的代码中的反序列化方法不能按预期方式工作。我可以得到我想要的东西,只需用你的反序列化代替我的反序列化。所以很复杂。
    猜你喜欢
    • 2021-01-08
    • 1970-01-01
    • 2020-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    • 2017-11-19
    相关资源
    最近更新 更多