为什么XmlReader / XmlSerializer在反序列化时弄乱了文本中的行跳转
本文关键字:文本 乱了 时弄 XmlReader XmlSerializer 反序列化 为什么 | 更新日期: 2023-09-27 18:08:17
我的对象template
,它是从手工制作的XML文件反序列化的,包含混合类型,文本可以包含行跳转。当我查看文本时,我可以看到行跳转是'r'n
,但在我的反序列化的template
对象中,行跳转是'n
。如何保持行跳转为'r'n
?
XmlReaderSettings settings = new XmlReaderSettings();
settings.CloseInput = true;
//settings.ValidationEventHandler += ValidationEventHandler;
settings.ValidationType = ValidationType.Schema;
settings.Schemas.Add(schema);
StringReader r = new StringReader(syntaxEdit.Text);
Schema.template rawTemplate = null;
using (XmlReader validatingReader = XmlReader.Create(r, settings))
{
try
{
XmlSerializer serializer = new XmlSerializer(typeof(Schema.template));
rawTemplate = serializer.Deserialize(validatingReader) as Schema.template;
}
catch (Exception ex)
{
rawTemplate = null;
string floro = ex.Message + (null != ex.InnerException ? ":'n" + ex.InnerException.Message : "");
MessageBox.Show(floro);
}
}
这似乎是XML规范所要求的行为,并且是Microsoft XmlReader实现中的一个"特性"(参见此回答)。
对你来说最简单的事情可能是用'r'n
代替'n
在你的结果
这是XML规范规定的行为:每个'r'n
, 'r
或'n
必须被解释为单个'n
字符。如果您想在输出中保留'r
,则必须将其更改为字符引用(
),如下所示。
public class StackOverflow_7374609
{
[XmlRoot(ElementName = "MyType", Namespace = "")]
public class MyType
{
[XmlText]
public string Value;
}
static void PrintChars(string str)
{
string toEscape = "'r'n't'b";
string escapeChar = "rntb";
foreach (char c in str)
{
if (' ' <= c && c <= '~')
{
Console.WriteLine(c);
}
else
{
int escapeIndex = toEscape.IndexOf(c);
if (escapeIndex >= 0)
{
Console.WriteLine("''{0}", escapeChar[escapeIndex]);
}
else
{
Console.WriteLine("''u{0:X4}", (int)c);
}
}
}
Console.WriteLine();
}
public static void Test()
{
string serialized = "<MyType>Hello'r'nworld</MyType>";
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(serialized));
XmlSerializer xs = new XmlSerializer(typeof(MyType));
MyType obj = (MyType)xs.Deserialize(ms);
Console.WriteLine("Without the replacement");
PrintChars(obj.Value);
serialized = serialized.Replace("'r", "
");
ms = new MemoryStream(Encoding.UTF8.GetBytes(serialized));
obj = (MyType)xs.Deserialize(ms);
Console.WriteLine("With the replacement");
PrintChars(obj.Value);
}
}