Question

I have a class with a property marked with [XmlText], that accepts multiline input. In my XML file, I've verified that the line endings inside the text content are infact "\r\n", the same as the rest of the file.

The code I'm using to deserialize is:

XmlSerializer configSerializer = new XmlSerializer(typeof(WorldList));
string file = "test.xml";

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

But, inside the setter for the [XmlText] property, value already has "\n" as a line ending. The main reason this is annoying is because "\n" line endings don't display properly in a TextBox... I'm not exactly sure which part is causing the problems, but I thought someone here might be able to shed some light on the situation.

Was it helpful?

Solution

I've change the sample code to make it easier to quickly put the code into a C# development environment. I've also deliberately not included using statements- it is only sample code.

For the example we have the follow class we wish to serialize:

   public class DataToSerialize
   {
       public string Name { get; set; }
   }

If we try to serialize and deserialize this in the way you describe the line where "Same" gets printed out will not get executed (I'm assuming the code will run on Windows with Environment.NewLine, replace with "\r\n" if you are not):

    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");
    }

However this can be fixed, by manually assigning an XmlTextReader to the serializer, with it's Normalization property set to false (the one used by default in the serializer is set to true):

    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");
    }

Same will now be printing out, which unless I am wrong is the behaviour you require?

OTHER TIPS

If you were serializing, then XmlWriterSettings.NewLineHandling (Replace) would be worth trying - but this won't help reading. A bit grungy, but perhaps do this directly in the setter:

private string text;
[XmlText]
public string Text {
    get { return text; }
    set 
    {
        Regex r = new Regex("(?<!\r)\n");
        text = r.Replace(value, "\r\n"); 
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top