我一直在敲打这个。似乎它必须是一个简单的解决方案,但我已经搜索了互联网并尝试了很多东西。
我有一个复杂的对象,其中包含一个字符串列表,需要序列化为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”。也许这个问题太多了。
任何见解都会非常感激。感谢。
答案 0 :(得分:2)
您需要使用XmlReader
和XmlWriter
课程或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");