How to keep XmlSerializer from killing NewLines in Strings?

后端 未结 5 1881
迷失自我
迷失自我 2020-12-08 07:00

Suppose I have a simple Class with just one Member a String.

public class Abc
{
    private String text;

    public String Text
    {
        get { return          


        
相关标签:
5条回答
  • 2020-12-08 07:04

    It is not the XmlSerializer but the XmlWriter which is removing your CR. To retain it we must have the writer convert CR to its character entity 
.

    XmlWriterSettings ws = new XmlWriterSettings();
    ws.NewLineHandling = NewLineHandling.Entitize;
    
    XmlSerializer ser = new XmlSerializer( typeof( Abc ) );
    using (XmlWriter wr = XmlWriter.Create( "abc.xml", ws )) {
        ser.Serialize( wr, s );
    }
    

    This is exactly the same with DataContractSerializer:

    var ser = new DataContractSerializer( typeof( Abc ) );
    using (XmlWriter wr = XmlWriter.Create( "abc.xml", ws )) {
        ser.Serialize( wr, s );
    }
    

    Why do we need to do this?

    This is because compliant XML parsers must, before parsing, translate CRLF and any CR not followed by a LF to a single LF. This behavior is defined in the End-of-Line handling section of the XML 1.0 specification.

    As this happens before parsing, you need to encode CR as its character entity if you want the CR to exist in the document.

    0 讨论(0)
  • 2020-12-08 07:11

    public class BinarySerialize where T : new() { public static string Serialize(T options, string path) {

                var xml = "";
                try
                {
                    File.Delete(path);
                }
                catch (Exception)
                {
    
    
                }
    
                try
                {
                    using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
                    {
                        var bf = new BinaryFormatter();
    
    
                        bf.Serialize(fs, options);
                    }
    
    
                }
                catch (Exception ex)
                {
    
                    return ex.Message;
                }
    
    
    
                return xml;
    
    
    
    
    
            }
    
            public static T Deserialize(string path)
            {
                T filteroptions;
                using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    var bf = new BinaryFormatter();
                    filteroptions = (T)bf.Deserialize(fs);
                }
                return filteroptions;
    
            }
        }
    
    0 讨论(0)
  • 2020-12-08 07:12

    Nice solution, Lachlan Roche!

    The function below (in VB.NET) uses a StringWriter to return a String, rather than writing the result to a file using an XmlWriter.

      ''' <summary>
      ''' Exports the object data to an XML formatted string.
      ''' Maintains CR characters after deserialization.
      ''' The object must be serializable to work.
      ''' </summary>
    
      Public Function ExportObjectXml(ByVal obj As Object) As String
        If obj Is Nothing Then
          Return String.Empty
        End If
    
        Dim serializer As New XmlSerializer(obj.GetType)
        Dim settings As New XmlWriterSettings With {.NewLineHandling = NewLineHandling.Entitize}
    
        Using output As New StringWriter
          Using writer As XmlWriter = XmlWriter.Create(output, settings)
            serializer.Serialize(writer, obj)
            Return output.ToString
          End Using
        End Using
      End Function
    
    0 讨论(0)
  • 2020-12-08 07:15
    public class SerializeAny<TF> where TF : new()
    {
        public static TF Deserialize(string serializedData)
        {
            try
            {
                var xmlSerializer = new XmlSerializer(typeof(TF));
                TF collection;
                using (var xmlReader = new XmlTextReader(serializedData, XmlNodeType.Document, null))
                {
                    collection = (TF)xmlSerializer.Deserialize(xmlReader);
                }
                return collection;
            }
            catch (Exception)
            {
    
    
            }
    
            return new TF();
        }
    
    
        public static TF DeserializeZip(string path)
        {
            try
            {
                var bytes = File.ReadAllBytes(path);
    
                string serializedData = Unzip(bytes);
    
                TF collection = Deserialize(serializedData);
    
    
                return collection;
            }
            catch (Exception)
            {
    
    
            }
    
            return new TF();
        }
    
        public static string Serialize(TF options)
        {
            var xml = "";
    
            try
            {
                var xmlSerializer = new XmlSerializer(typeof(TF));
                using (var stringWriter = new StringWriter())
                {
                    xmlSerializer.Serialize(stringWriter, options);
                    xml = stringWriter.ToString();
                }
            }
            catch (Exception ex)
            {
    
                return ex.Message;
            }
    
    
    
            return xml;
        }
    
        public static string SerializeZip(TF options, string path)
        {
            var xml = "";
    
            try
            {
                xml = Serialize(options);
                var zip = Zip(xml);
                File.WriteAllBytes(path, zip);
            }
            catch (Exception ex)
            {
    
                return ex.Message;
            }
    
    
    
            return xml;
        }
    
    
    
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times")]
        internal static String SerializeObject<T>(T obj, Encoding enc)
        {
            using (var ms = new MemoryStream())
            {
                var xmlWriterSettings = new System.Xml.XmlWriterSettings()
                {
                    // If set to true XmlWriter would close MemoryStream automatically and using would then do double dispose
                    // Code analysis does not understand that. That's why there is a suppress message.
                    CloseOutput = false,
                    Encoding = enc,
                    OmitXmlDeclaration = false,
                    Indent = true
                };
                using (var xw = XmlWriter.Create(ms, xmlWriterSettings))
                {
                    var s = new XmlSerializer(typeof(T));
                    s.Serialize(xw, obj);
                }
    
                return enc.GetString(ms.ToArray());
            }
        }
    
        private static void CopyTo(Stream src, Stream dest)
        {
            byte[] bytes = new byte[4096];
    
            int cnt;
    
            while ((cnt = src.Read(bytes, 0, bytes.Length)) != 0)
            {
                dest.Write(bytes, 0, cnt);
            }
        }
    
        private static byte[] Zip(string str)
        {
            var bytes = Encoding.UTF8.GetBytes(str);
    
            using (var msi = new MemoryStream(bytes))
            using (var mso = new MemoryStream())
            {
                using (var gs = new GZipStream(mso, CompressionMode.Compress))
                {
                    //msi.CopyTo(gs);
                    CopyTo(msi, gs);
                }
    
                return mso.ToArray();
            }
        }
    
        private static string Unzip(byte[] bytes)
        {
            using (var msi = new MemoryStream(bytes))
            using (var mso = new MemoryStream())
            {
                using (var gs = new GZipStream(msi, CompressionMode.Decompress))
                {
                    CopyTo(gs, mso);
                }
    
                return Encoding.UTF8.GetString(mso.ToArray());
            }
        }
    
    }
    
    0 讨论(0)
  • 2020-12-08 07:25

    Use this code:

    public static FilterOptions Deserialize(string serializedData)
    {
        try
        {
            var xmlSerializer = new XmlSerializer(typeof(FilterOptions));
            var xmlReader = new XmlTextReader(serializedData,XmlNodeType.Document,null);
            var collection = (FilterOptions)xmlSerializer.Deserialize(xmlReader);
            return collection;
        }
        catch (Exception)
        {
    
    
        }
    
        return new FilterOptions();
    }
    
    0 讨论(0)
提交回复
热议问题