객체를 XML 문자열로 변환


90

WebserviceTypeXSD 파일의 xsd.exe 도구에서 얻은 클래스 가 있습니다.

이제 WebServiceType개체 의 인스턴스를 문자열 로 deserialize하고 싶습니다 . 어떻게 할 수 있습니까?

MethodCheckTypePARAMS 같은 목적 갖는 WebServiceType어레이.

내 첫 번째 시도는 직렬화하는 것과 같았습니다. a XmlSerializer및 a StringWriter(직렬화하는 동안 a를 사용했습니다 StringReader).

이것은 WebServiceType객체를 직렬화하는 방법입니다 .

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;

편집하다:

다른 단어로 말할 수도 있습니다.이 MethodCheckType객체의 인스턴스가 있고 다른 한편으로는이 객체를 직렬화 한 XML 문서가 있습니다. 이제이 인스턴스를 문자열 형식의 XML 문서로 변환하고 싶습니다. 이 후 두 문자열 (XML 문서)이 동일한 지 증명해야합니다. XML 문서를 a로 읽고 StringReader이를 MethodCheckType객체 로 직렬화 하는 첫 번째 메서드의 단위 테스트를 만들기 때문에이 작업을 수행해야 합니다.


2
어떤 오류가 발생합니까? 그리고 용어를 혼동 할 수 있습니다. 직렬화 (XML 세계에서)는 객체에서 XML로 변환 하는 것입니다 . deserialization은 XML에서 객체로 변환 됩니다 . XML 문자열 에서 객체를 역 직렬화 하시겠습니까?
carlosfigueira

답변:


193

두 가지 방법에 대한 변환 방법은 다음과 같습니다. this = 클래스의 인스턴스

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
올바른 리소스 해제를 위해 using패턴 또는 호출 Dispose방법을 사용해야합니다 .
Ivan Kochurkin 2013

관리되지 않는 코드가 사용되지 않는 것보다 모든 CLR 버전에 대해 확인해야합니다.
AlphaOmega 2014

3
왜? 리소스를 많이 사용하는 모든 것을 폐기해야하기 때문입니다 (관리되지 않고 관리 됨 ). 가비지 컬렉터가 당신을 위해 정리 해줄 것이기 때문에 (결국) 당신이 그 일을 지나치게 어렵게 만들어야한다는 의미는 아닙니다. 진행하면서 정리하면 코드가 더 효율적입니다. 이유를 명시 적으로 폐기에 대한 자세한 정보를 원하시면 여기 좋은 아이디어입니다
리암

1
명확성을 위해. 너희들은 (XmlSerializer를이 폐기 방법을 가지고 있지 않기 때문에) StringWriter 클래스와 StringReader를를 배치하는 얘기
공생을

함수의 끝이 리소스를 효율적으로 해제하지 using않습니까? @KvanTTT?
Mark Entingh

79

나는 이것이 매우 오래된 게시물이라는 것을 알고 있지만 LB의 답변을 살펴본 후 수용 된 답변을 개선하고 내 응용 프로그램에 일반적으로 만들 수있는 방법에 대해 생각했습니다. 내가 생각 해낸 것은 다음과 같습니다.

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

이제 이러한 메서드를 정적 도우미 클래스에 배치 할 수 있습니다. 즉, 직렬화해야하는 모든 클래스에 코드가 중복되지 않습니다.


10
"Serialize"메서드에서 typeof (T) 대신 dataToSerialize.GetType ()을 사용합니다. 언뜻보기에는 T를 유형으로 사용하는 것이 안전 해 보이지만 "dataToSerialize"개체가 부모 유형 (ChildClass가 BaseClass로 캐스트)로 캐스트 된 경우 오류가 발생합니다. 그리고 물론 먼저 null인지 확인하십시오.
폴 부활절

1
다른 일을하지 않고 다시 던지기 위해 잡는 이유는 무엇입니까?
분쇄

좋은 질문입니다. 저는 여기에서 기능에 대한 프레임 워크 만 전체 그림을 개발하려고하지 않았으며 예외를 삼키는 예제를 제공하고 싶지 않았습니다. 당시에는 훌륭하고 일반적인 대안처럼 보였습니다. 개선 사항을 자유롭게 제안하십시오!
William Smith

재사용 가능한 좋은 솔루션.
Nitesh Saxena 2018

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
Serialize에는 제네릭이 필요합니다. 개체면 충분합니다. if (dataToSerialize == null) null 반환; ... var serializer = new XmlSerializer (dataToSerialize.GetType ()); ...
AlphaOmega 2014

0

이것은 내 솔루션입니다. 모든 목록 개체에 대해이 코드를 사용하여 xml 레이아웃으로 변환 할 수 있습니다. KeyFather는 주요 태그이고 KeySon은 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();
        }
    }

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);
        }
    }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.