关于c#:XML反序列化’标准化’行结尾,如何阻止它?

XML deserialization 'standardising' line endings, how to stop it? (.NET)

我有一个类,其属性标记为[XmlText],它接受多行输入。在我的XML文件中,我已经验证了文本内容中的行尾与文件的其余部分是一致的。

我用来反序列化的代码是:

1
2
3
4
5
6
7
8
9
10
XmlSerializer configSerializer = new XmlSerializer(typeof(WorldList));
string file ="test.xml";

if (File.Exists(file))
{
    using (TextReader r = new StreamReader(file))
    {
        foo = configSerializer.Deserialize(r);
    }
}

但是,在[XmlText]属性的setter中,value已经将"
"
作为行尾。这让人恼火的主要原因是"
"
行尾在TextBox中没有正确显示。我不确定是哪一部分造成了这些问题,但我认为这里的一些人可能能够对这种情况有所了解。


我已经更改了示例代码,使其更容易快速地将代码放入C开发环境中。我还故意不包括使用语句-它只是示例代码。

例如,我们希望序列化以下类:

1
2
3
4
   public class DataToSerialize
   {
       public string Name { get; set; }
   }

如果我们尝试按您描述的方式序列化和反序列化此代码,将不会执行"相同"的输出行(我假设代码将在带有environment.newline的Windows上运行,如果不执行,则替换为"
"):

1
2
3
4
5
6
7
8
9
10
11
12
    DataToSerialize test = new DataToSerialize();
    test.Name ="TestData" + Environment.NewLine;
    XmlSerializer configSerializer = new XmlSerializer(typeof(DataToSerialize));
    MemoryStream ms = new MemoryStream();
    StreamWriter sw = new StreamWriter(ms);
    configSerializer.Serialize(sw, test);
    ms.Position = 0;
    DataToSerialize deserialized = (DataToSerialize)configSerializer.Deserialize(ms);
    if (deserialized.Name.Equals("TestData" + Environment.NewLine))
    {
        Console.WriteLine("Same");
    }

但是,可以通过手动将xmlTextReader分配给序列化程序来修复此问题,将其规范化属性设置为false(默认情况下,序列化程序中使用的属性设置为true):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    DataToSerialize test = new DataToSerialize();
    test.Name ="TestData" + Environment.NewLine;
    XmlSerializer configSerializer = new XmlSerializer(typeof(DataToSerialize));
    MemoryStream ms = new MemoryStream();
    StreamWriter sw = new StreamWriter(ms);

    configSerializer.Serialize(sw, test);
    ms.Position = 0;
    XmlTextReader reader = new XmlTextReader(ms);
    reader.Normalization = false;
    DataToSerialize deserialized = (DataToSerialize)configSerializer.Deserialize(reader);
    if (deserialized.Name.Equals("TestData" + Environment.NewLine))
    {
        Console.WriteLine("Same");
    }

现在也会打印出来,除非我错了,否则你要求的行为是什么?


如果你正在序列化,那么XmlWriterSettings.NewLineHandling(Replace)就值得尝试了——但这不会有助于阅读。有点笨拙,但也许直接在setter中这样做:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private string text;
[XmlText]
public string Text {
    get { return text; }
    set
    {
        Regex r = new Regex("(?<!
)
"
);
        text = r.Replace(value,"

"
);
    }
}