オブジェクトをXML文字列に変換します


88

WebserviceTypeXSDファイルのツールxsd.exeから取得したという名前のクラスがあります。

ここで、WebServiceTypeオブジェクトのインスタンスを文字列に逆シリアル化します。これどうやってするの?

MethodCheckTypeparamsはのようにオブジェクトが持つWebServiceType配列。

私の最初の試みは、それをシリアル化したようなものでした:aXmlSerializerとaStringWriterを使用しました(シリアル化中にはを使用しました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ます。


2
どのようなエラーが発生しますか?そして、あなたは用語を混乱させるかもしれません:シリアル化(XMLの世界で)はオブジェクトからXMLに変換しています; デシリアライズとは、XMLからオブジェクトに変換することです。XML文字列からオブジェクトを逆シリアル化しますか?
carlosfigueira 2012

回答:


188

両方向の変換方法は次のとおりです。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 ;
        }
    }

13
正しいリソース解放には、usingpatternまたはcallDisposeメソッドを使用する必要があります。
Ivan Kochurkin 2013年

アンマネージコードが使用されていないことを確認する必要があります。
alphaOmega 2014

3
どうして?リソースを大量に消費するもの(管理されてないものと管理されているもの)はすべて破棄する必要があるためです。ガベージコレクターが(最終的に)あなたのためにクリーンアップするからといって、あなたがそれを過度に困難にする必要があるという意味ではありません。作業を進めながらクリーンアップすると、コードがより効率的になります。明示的な処分が良い考えである理由の詳細はこちら
Liam

1
わかりやすくするために。君たちは(XmlSerializerをのDisposeメソッドを持っていないよう)にStringWriterとにStringReaderを配置について話している
共生を

関数の終わりは、リソースを同じくらい効率的に解放しませんusingか?@KvanTTT?
Mark Entingh 2017

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
「Serialize」メソッドでは、typeof(T)の代わりにdataToSerialize.GetType()を使用します。一見、Tを型として使用しても安全に見えますが、「dataToSerialize」オブジェクトが親型にキャストされている場合(ChildClassがBaseClassにキャストされている場合)、エラーがスローされます。もちろん、最初にnullを確認してください。
ポールイースター

1
何もせずに投げ直すだけで捕まえる意味は何ですか?
クラッシュ

素晴らしい質問です。ここでは、機能のフレームワークだけで全体像を作成しようとはしていませんでした。例外を飲み込むような例を挙げたくはありませんでした。当時は、優れた一般的な代替手段のように見えました。改善を提案してください!
ミス

優れた再利用可能なソリューション。
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
シリアル化にはジェネリックが必要です。オブジェクトで十分です。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.