Przekonwertuj obiekt na ciąg XML

88

Mam klasę o nazwie, WebserviceTypektórą otrzymałem z narzędzia xsd.exe z pliku XSD.

Teraz chcę deserializować wystąpienie WebServiceTypeobiektu do ciągu. Jak mogę to zrobić?

MethodCheckTypePrzedmiot ma za params w WebServiceTypetablicy.

Moja pierwsza próba była taka, jakbym ją serializował: z a XmlSerializeri StringWriter(podczas serializacji użyłem a StringReader).

Oto metoda, w której serializuję WebServiceTypeobiekt:

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;

Edytować:

Może mógłbym to powiedzieć innymi słowami: mam instancję tego MethodCheckTypeobiektu, az drugiej strony mam dokument XML, z którego serializowałem ten obiekt. Teraz chcę przekonwertować to wystąpienie na dokument XML w postaci ciągu. Następnie muszę udowodnić, czy oba ciągi znaków (dokumentów XML) są takie same. Muszę to zrobić, ponieważ wykonuję testy jednostkowe pierwszej metody, w której wczytuję dokument XML do a StringReaderi serializuję go do MethodCheckTypeobiektu.

FluepkeSchaeng
źródło
2
Jaki błąd otrzymujesz? I możesz mylić terminy: serializacja (w świecie XML) to konwertowanie z obiektu do XML ; deserializacja to konwertowanie z XML do obiektu . Czy chcesz deserializować obiekt z ciągu XML?
carlosfigueira

Odpowiedzi:

189

Oto metoda konwersji dla obu sposobów. this = instancja Twojej klasy

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 ;
        }
    }
Tomas Grosup
źródło
14
W celu poprawnego zwalniania zasobów należy użyć usingwzorca lub Disposemetody wywołania .
Ivan Kochurkin
Musisz mieć pewność, że dla wszystkich wersji CLR kod niezarządzany nie jest używany.
AlphaOmega
3
Czemu? Ponieważ należy pozbyć się wszystkiego, co wymaga dużej ilości zasobów (niezarządzane i zarządzane ). Tylko dlatego, że śmieciarz posprząta za Ciebie (w końcu), nie oznacza, że ​​powinieneś utrudniać jego pracę. Porządkuj w miarę postępów, a Twój kod będzie bardziej wydajny. Więcej informacji na temat tego, dlaczego wyraźne pozbywanie się jest dobrym pomysłem tutaj
Liam
1
tylko dla jasności. mówicie o pozbyciu się StringWriter i StringReader (ponieważ XmlSerializer nie ma metody Dispose)
symbiont
czy koniec funkcji nie zwalnia zasobów tak wydajnie, jak using? @KvanTTT?
Mark Entingh
77

Zdaję sobie sprawę, że to bardzo stary post, ale po przyjrzeniu się odpowiedzi LB pomyślałem, jak mogę ulepszyć zaakceptowaną odpowiedź i uczynić ją ogólną dla mojej własnej aplikacji. Oto, co wymyśliłem:

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

Te metody można teraz umieścić w statycznej klasie pomocniczej, co oznacza brak duplikowania kodu do każdej klasy wymagającej serializacji.

Williama Smitha
źródło
10
W metodzie „Serialize” użyj dataToSerialize.GetType () zamiast typeof (T). Na pierwszy rzut oka użycie T jako typu wydaje się bezpieczne, ale jeśli obiekt „dataToSerialize” został rzutowany na typ nadrzędny (rzutowanie ChildClass na BaseClass), zgłosi błąd. I oczywiście najpierw sprawdź, czy jest null.
Wielkanoc Pawła
1
Jaki jest sens łapania tylko po to, by ponownie rzucić bez robienia czegokolwiek innego?
zmiażdżyć
Świetne pytanie; Nie próbowałem tworzyć tutaj pełnego obrazu, tylko ramy dla funkcjonalności i zdecydowanie nie chciałem podawać przykładu, który połyka wyjątek. Wtedy wydawało się, że to dobra, ogólna alternatywa. Zapraszam do sugerowania ulepszeń!
William Smith
Dobre rozwiązanie wielokrotnego użytku.
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);
        }
    }
Elanchezhian Narayanasamy
źródło
1
Serialize potrzebuje typów generycznych. Obiekt wystarczy. if (dataToSerialize == null) return null; ... var serializer = new XmlSerializer (dataToSerialize.GetType ()); ...
AlphaOmega
0

To jest moje rozwiązanie, dla dowolnego obiektu listy możesz użyć tego kodu do konwersji do układu XML. KeyFather to Twój główny tag, a KeySon to miejsce, w którym zaczniesz Forech.

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();
        }
    }
Fred Peixoto
źródło
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);
        }
    }
O Thạnh Ldt
źródło