为什么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);
    }
}

为什么XmlReader / XmlSerializer在反序列化时弄乱了文本中的行跳转

这似乎是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", "&#xD;");
        ms = new MemoryStream(Encoding.UTF8.GetBytes(serialized));
        obj = (MyType)xs.Deserialize(ms);
        Console.WriteLine("With the replacement");
        PrintChars(obj.Value);
    }
}