Bir nesneyi XML dizesine dönüştürme


92

WebserviceTypeBir XSD dosyasından xsd.exe aracından aldığım bir sınıfım var.

Şimdi, bir WebServiceTypenesnenin bir örneğini bir dizeye serisini kaldırmak istiyorum . Bunu nasıl yapabilirim?

MethodCheckTypeBir params olarak nesne, WebServiceTypebir dizi.

İlk denemem onu ​​serileştirmiş gibiydi: a XmlSerializerve a ile StringWriter(serileştirirken a kullandım StringReader).

WebServiceTypeNesneyi serileştirdiğim yöntem budur :

XmlSerializer serializer = new XmlSerializer(typeof(MethodCheckType));
        MethodCheckType output = null;
        StringReader reader = null;

        // catch global exception, logg it and throw it
        try
        {
            reader = new StringReader(path);
            output = (MethodCheckType)serializer.Deserialize(reader);
        }
        catch (Exception)
        {
            throw;
        }
        finally
        {
            reader.Dispose();
        }

        return output.WebService;

Düzenle:

Belki farklı kelimelerle söyleyebilirim: Bu MethodCheckTypenesnenin bir örneğine sahibim ve diğer yandan bu nesneyi serileştirdiğim XML belgesine sahibim. Şimdi bu örneği bir dize biçiminde bir XML belgesine dönüştürmek istiyorum. Bundan sonra, her iki dizenin de (XML belgelerinin) aynı olup olmadığını kanıtlamalıyım. Bunu yapmak zorundayım, çünkü bir XML belgesini StringReadera'ya okuduğum ve onu bir MethodCheckTypenesne olarak serileştirdiğim ilk yöntemin birim testlerini yapıyorum .


2
Hangi hatayı alıyorsun? Ve terimleri karıştırıyor olabilirsiniz: serileştirme (XML dünyasında) bir nesneden XML'e dönüştürmektir ; seriyi kaldırma, XML'den bir nesneye dönüştürmektir . Bir nesnedeki seriyi kaldırmak için wanto Do gelen bir XML dizesi?
carlosfigueira

Yanıtlar:


195

Her iki yol için de dönüştürme yöntemi. this = sınıfınızın örneği

public string ToXML()
    {
        using(var stringwriter = new System.IO.StringWriter())
        { 
            var serializer = new XmlSerializer(this.GetType());
            serializer.Serialize(stringwriter, this);
            return stringwriter.ToString();
        }
    }

 public static YourClass LoadFromXMLString(string xmlText)
    {
        using(var stringReader = new System.IO.StringReader(xmlText))
        {
            var serializer = new XmlSerializer(typeof(YourClass ));
            return serializer.Deserialize(stringReader) as YourClass ;
        }
    }

14
Doğru kaynak yayınlaması için usingdesen veya çağrı Disposeyöntemini kullanmalısınız .
Ivan Kochurkin

Yönetilmeyen kod kullanılmadığından tüm CLR sürümleri için emin olmalısınız.
AlphaOmega

3
Neden? Çünkü yoğun kaynak gerektiren (yönetilmeyen ve yönetilen ) her şeyi atmalısınız . Çöp toplayıcının sizin için temizleyeceği (sonunda), işini gereksiz yere zorlaştırmanız gerektiği anlamına gelmez. İlerledikçe temizleyin ve kodunuz daha verimli olacaktır. Açıkça imha etmenin neden iyi bir fikir olduğu hakkında daha fazla bilgi burada
Liam

1
sadece açıklık için. StringWriter ve StringReader'ı elden çıkarmaktan bahsediyorsunuz (XmlSerializer'ın Dispose yöntemi olmadığı için)
symbiont

işlevin sonu kaynakları olduğu kadar verimli bir şekilde serbest bırakmıyor usingmu? @KvanTTT?
Mark Entingh

79

Bunun çok eski bir gönderi olduğunun farkındayım, ancak LB'nin yanıtına baktıktan sonra, kabul edilen yanıtı nasıl geliştirebileceğimi ve bunu kendi başvurum için genel hale getirebileceğimi düşündüm. İşte bulduğum şey:

public static string Serialize<T>(T dataToSerialize)
{
    try
    {
        var stringwriter = new System.IO.StringWriter();
        var serializer = new XmlSerializer(typeof(T));
        serializer.Serialize(stringwriter, dataToSerialize);
        return stringwriter.ToString();
    }
    catch
    {
        throw;
    }
}

public static T Deserialize<T>(string xmlText)
{
    try
    {
        var stringReader = new System.IO.StringReader(xmlText);
        var serializer = new XmlSerializer(typeof(T));
        return (T)serializer.Deserialize(stringReader);
    }
    catch
    {
        throw;
    }
}

Bu yöntemler artık statik bir yardımcı sınıfa yerleştirilebilir; bu, serileştirilmesi gereken her sınıf için kod çoğaltması olmadığı anlamına gelir.


10
"Serialize" yönteminde typeof (T) yerine dataToSerialize.GetType () kullanın. İlk bakışta bu tür olarak T'yi kullanmak güvenli görünür, ancak "dataToSerialize" nesnesi bir üst türe dönüştürülürse (ChildClass, BaseClass'a dönüştürülür) bir hata verir. Ve elbette önce boş olup olmadığını kontrol edin.
Paul Easter

1
Başka hiçbir şey yapmadan yeniden fırlatmak için yakalamanın anlamı nedir?
ezmek

Harika soru; Burada sadece işlevsellik çerçevesi için tam bir resim geliştirmeye çalışmıyordum ve kesinlikle istisnayı yutan bir örnek vermek istemedim. O zamanlar iyi ve genel bir alternatif gibi görünüyordu. İyileştirmeler önermekten çekinmeyin!
William Smith

İyi yeniden kullanılabilir çözüm.
Nitesh Saxena

21
    public static string Serialize(object dataToSerialize)
    {
        if(dataToSerialize==null) return null;

        using (StringWriter stringwriter = new System.IO.StringWriter())
        {
            var serializer = new XmlSerializer(dataToSerialize.GetType());
            serializer.Serialize(stringwriter, dataToSerialize);
            return stringwriter.ToString();
        }
    }

    public static T Deserialize<T>(string xmlText)
    {
        if(String.IsNullOrWhiteSpace(xmlText)) return default(T);

        using (StringReader stringReader = new System.IO.StringReader(xmlText))
        {
            var serializer = new XmlSerializer(typeof(T));
            return (T)serializer.Deserialize(stringReader);
        }
    }

1
Seri hale getirmenin jeneriklere ihtiyacı var. Nesne yeterlidir. eğer (dataToSerialize == null) null döndür; ... var serializer = new XmlSerializer (dataToSerialize.GetType ()); ...
AlphaOmega

0

Bu benim çözümüm, herhangi bir liste nesnesi için bu kodu xml düzenine dönüştürmek için kullanabilirsiniz. KeyFather sizin ana etiketinizdir ve KeySon Forech'inize başlayacağınız yerdir.

public string BuildXml<T>(ICollection<T> anyObject, string keyFather, string keySon)
    {
        var settings = new XmlWriterSettings
        {
            Indent = true
        };
        PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(T));
        StringBuilder builder = new StringBuilder();
        using (XmlWriter writer = XmlWriter.Create(builder, settings))
        {
            writer.WriteStartDocument();
            writer.WriteStartElement(keyFather);
            foreach (var objeto in anyObject)
            {
                writer.WriteStartElement(keySon);
                foreach (PropertyDescriptor item in props)
                {
                    writer.WriteStartElement(item.DisplayName);
                    writer.WriteString(props[item.DisplayName].GetValue(objeto).ToString());
                    writer.WriteEndElement();
                }
                writer.WriteEndElement();
            }
            writer.WriteFullEndElement();
            writer.WriteEndDocument();
            writer.Flush();
            return builder.ToString();
        }
    }

0
 public static class XMLHelper
    {
        /// <summary>
        /// Usage: var xmlString = XMLHelper.Serialize<MyObject>(value);
        /// </summary>
        /// <typeparam name="T">Kiểu dữ liệu</typeparam>
        /// <param name="value">giá trị</param>
        /// <param name="omitXmlDeclaration">bỏ qua declare</param>
        /// <param name="removeEncodingDeclaration">xóa encode declare</param>
        /// <returns>xml string</returns>
        public static string Serialize<T>(T value, bool omitXmlDeclaration = false, bool omitEncodingDeclaration = true)
        {
            if (value == null)
            {
                return string.Empty;
            }
            try
            {
                var xmlWriterSettings = new XmlWriterSettings
                {
                    Indent = true,
                    OmitXmlDeclaration = omitXmlDeclaration, //true: remove <?xml version="1.0" encoding="utf-8"?>
                    Encoding = Encoding.UTF8,
                    NewLineChars = "", // remove \r\n
                };

                var xmlserializer = new XmlSerializer(typeof(T));

                using (var memoryStream = new MemoryStream())
                {
                    using (var xmlWriter = XmlWriter.Create(memoryStream, xmlWriterSettings))
                    {
                        xmlserializer.Serialize(xmlWriter, value);
                        //return stringWriter.ToString();
                    }

                    memoryStream.Position = 0;
                    using (var sr = new StreamReader(memoryStream))
                    {
                        var pureResult = sr.ReadToEnd();
                        var resultAfterOmitEncoding = ReplaceFirst(pureResult, " encoding=\"utf-8\"", "");
                        if (omitEncodingDeclaration)
                            return resultAfterOmitEncoding;
                        return pureResult;
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception("XMLSerialize error: ", ex);
            }
        }

        private static string ReplaceFirst(string text, string search, string replace)
        {
            int pos = text.IndexOf(search);

            if (pos < 0)
            {
                return text;
            }

            return text.Substring(0, pos) + replace + text.Substring(pos + search.Length);
        }
    }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.