为什么在反序列化时XmlReader / XmlSerializer会破坏文本中的行跳转?

时间:2011-09-10 20:48:13

标签: c# xml-serialization xmlserializer

我的对象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);
    }
}

2 个答案:

答案 0 :(得分:2)

这似乎是XML规范所必需的行为,并且是Microsoft的XmlReader(see this answer)实现中的“功能”。

您最简单的做法可能是在结果中将\n替换为\r\n

答案 1 :(得分:2)

这就是行为mandated by the XML specification:每个\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);
    }
}