将对象转换为XML字符串


88

我有一个名为WebserviceTypeXsd.exe的类,它来自XSD文件。

现在,我想将WebServiceType对象的实例反序列化为字符串。我怎样才能做到这一点?

MethodCheckType对象具有一个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文档读入aStringReader并将其序列化为一个MethodCheckType对象。


2
你得到什么错误?您可能会混淆以下术语:序列化(在XML世界中)是从对象转换为XML;反序列化是从XML转换为对象。是否要从XML字符串反序列化对象?
carlosfigueira

Answers:


188

这是两种方式的转换方法。这=类的实例

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

13
您应该使用using模式或调用Dispose方法来正确释放资源。
Ivan Kochurkin 2013年

您必须确保所有CLR版本都未使用非托管代码。
AlphaOmega 2014年

3
为什么?因为您应该处理所有资源密集型的事情(非托管和托管)。只是因为垃圾收集器将为您清理(最终)并不意味着您应该使它的工作异常困难。继续进行清理,代码会更高效。为什么明确的优化配置更多信息是一个好主意,在这里
利亚姆

1
为了清楚起见。你们正在谈论处理StringWriter和StringReader(因为XmlSerializer没有Dispose方法)
symbiont

函数的末尾释放资源的效率using不是吗?@KvanTTT?
Mark Entingh '17

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。
Paul Easter

1
不做任何其他事情而仅仅赶回去的意义何在?
暗恋

好问题;我并不是在这里只是为功能框架开发完整的图片,我当然也不想举一个吞下异常的例子。在当时似乎是一个很好的通用替代方案。随时提出改进建议!
威廉·史密斯

好的可重用解决方案。
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
序列化确实需要泛型。对象就足够了。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);
        }
    }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.