Преобразование объекта в строку XML

89

У меня есть класс с именем, который WebserviceTypeя получил от инструмента xsd.exe из файла XSD.

Теперь я хочу десериализовать экземпляр WebServiceTypeобъекта в строку. Как я могу это сделать?

MethodCheckTypeОбъект имеет , как Params в WebServiceTypeмассив.

Моя первая попытка была как будто я сериализовал его: с помощью XmlSerializerи StringWriter(при сериализации я использовал 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-документ в StringReaderи сериализую его в MethodCheckTypeобъект.

FluepkeSchaeng
источник
2
Какая у вас ошибка? И вы можете запутать термины: сериализация (в мире XML) - это преобразование объекта в XML ; десериализация - это преобразование из XML в объект . Вы хотите десериализовать объект из строки XML?
carlosfigueira

Ответы:

190

Вот метод преобразования для обоих способов. 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метод вызова для правильного высвобождения ресурсов.
Иван Кочуркин
Вы должны быть уверены, что для всех версий CLR не используется неуправляемый код.
AlphaOmega
3
Зачем? Потому что вы должны утилизировать все, что является ресурсоемким (неуправляемым и управляемым ). Просто потому, что сборщик мусора очистит за вас (в конце концов), это не означает, что вы должны сделать его работу чрезмерно сложной. Убирайте по мере продвижения, и ваш код станет более эффективным. Подробнее о том, почему явная утилизация - хорошая идея, можно здесь
Лиам,
1
просто для ясности. вы, ребята, говорите об утилизации StringWriter и StringReader (поскольку XmlSerializer не имеет метода Dispose)
симбионт
разве конец функции не высвобождает ресурсы так же эффективно, как using? @KvanTTT?
Марк Энтинг,
77

Я понимаю, что это очень старый пост, но, посмотрев на ответ 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
В методе «Сериализация» используйте dataToSerialize.GetType () вместо typeof (T). На первый взгляд кажется безопасным использовать T в качестве типа, но если объект «dataToSerialize» был приведен к родительскому типу (преобразование ChildClass в BaseClass), это вызовет ошибку. И, конечно, сначала проверьте его на null.
Пол Истер
1
Какой смысл ловить, чтобы просто перебросить, ничего не делая?
Crush
Отличный вопрос; Я не пытался представить здесь полную картину, а просто рамку функциональности, и я определенно не хотел приводить пример, который проглатывает исключение. В то время это казалось хорошей альтернативой. Не стесняйтесь предлагать улучшения!
Уильям Смит
Хорошее многоразовое решение.
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
Для сериализации нужны дженерики. Объекта достаточно. если (dataToSerialize == null) return null; ... var serializer = new XmlSerializer (dataToSerialize.GetType ()); ...
AlphaOmega
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);
        }
    }
O Thạnh Ldt
источник