Konvertieren Sie ein Objekt in eine XML-Zeichenfolge

87

Ich habe eine Klasse mit dem Namen, die WebserviceTypeich vom Tool xsd.exe aus einer XSD-Datei erhalten habe.

Jetzt möchte ich eine Instanz eines WebServiceTypeObjekts in eine Zeichenfolge deserialisieren . Wie kann ich das machen?

Das MethodCheckTypeObjekt hat als Parameter ein WebServiceTypeArray.

Mein erster Versuch war, als hätte ich ihn serialisiert: mit a XmlSerializerund a StringWriter(während der Serialisierung habe ich a verwendet StringReader).

Dies ist die Methode, mit der ich das WebServiceTypeObjekt serialisiere :

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;

Bearbeiten:

Vielleicht könnte ich es mit anderen Worten sagen: Ich habe eine Instanz dieses MethodCheckTypeObjekts und andererseits habe ich das XML-Dokument, aus dem ich dieses Objekt serialisiert habe. Jetzt möchte ich diese Instanz in Form einer Zeichenfolge in ein XML-Dokument konvertieren. Danach muss ich prüfen, ob beide Zeichenfolgen (von XML-Dokumenten) gleich sind. Dies muss ich tun, weil ich Unit-Tests der ersten Methode durchführe, bei der ich ein XML-Dokument StringReaderin ein MethodCheckTypeObjekt einlese und es in ein Objekt serialisiere .

FluepkeSchaeng
quelle
2
Welchen Fehler bekommen Sie? Und Sie können die Begriffe verwirren: Die Serialisierung (in der XML-Welt) konvertiert von einem Objekt in XML . Die Deserialisierung konvertiert von XML in ein Objekt . Möchten Sie ein Objekt aus einer XML-Zeichenfolge deserialisieren ?
Carlosfigueira

Antworten:

186

Hier sind Konvertierungsmethoden für beide Möglichkeiten. this = Instanz Ihrer Klasse

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
quelle
13
Sie sollten die usingMuster- oder Aufrufmethode Disposefür die korrekte Freigabe von Ressourcen verwenden.
Ivan Kochurkin
Sie müssen sicher sein, dass für alle CLR-Versionen nicht verwalteter Code nicht verwendet wird.
AlphaOmega
3
Warum? Weil Sie alles entsorgen sollten, was ressourcenintensiv ist (nicht verwaltet und verwaltet ). Nur weil der Müllsammler (irgendwann) für Sie aufräumt, heißt das nicht, dass Sie seine Arbeit übermäßig schwierig machen sollten. Räumen Sie auf, während Sie fortfahren, und Ihr Code wird effizienter. Weitere Informationen darüber, warum explizite Entsorgung eine gute Idee ist, finden Sie hier
Liam
1
nur zur Klarheit. ihr redet über das Entsorgen von StringWriter und StringReader (da XmlSerializer keine Dispose-Methode hat)
Symbiont
Gibt das Ende der Funktion Ressourcen nicht genauso effizient frei wie using? @KvanTTT?
Mark Entingh
76

Mir ist klar, dass dies ein sehr alter Beitrag ist, aber nachdem ich mir die Antwort von LB angesehen hatte, dachte ich darüber nach, wie ich die akzeptierte Antwort verbessern und sie für meine eigene Bewerbung generisch machen könnte. Folgendes habe ich mir ausgedacht:

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

Diese Methoden können jetzt in eine statische Hilfsklasse eingefügt werden. Dies bedeutet, dass keine Code-Duplizierung für jede Klasse erfolgt, die serialisiert werden muss.

William Smith
quelle
10
Verwenden Sie bei der Methode "Serialize" dataToSerialize.GetType () anstelle von typeof (T). Auf den ersten Blick scheint es sicher, T als Typ zu verwenden, aber wenn das Objekt "dataToSerialize" in einen übergeordneten Typ umgewandelt wurde (ChildClass in BaseClass umgewandelt), wird ein Fehler ausgegeben. Und überprüfen Sie es natürlich zuerst auf Null.
Paul Easter
1
Was bringt es, nur um zu werfen, ohne etwas anderes zu tun?
Crush
Gute Frage; Ich habe hier nicht versucht, ein vollständiges Bild zu entwickeln, nur den Rahmen für die Funktionalität, und ich wollte definitiv kein Beispiel geben, das die Ausnahme verschluckt. Schien damals eine gute, generische Alternative zu sein. Fühlen Sie sich frei, Verbesserungen vorzuschlagen!
William Smith
Gute wiederverwendbare Lösung.
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
quelle
1
Serialize benötigt Generika. Objekt ist genug. if (dataToSerialize == null) gibt null zurück; ... var serializer = neuer XmlSerializer (dataToSerialize.GetType ()); ...
AlphaOmega
0

Dies ist meine Lösung. Für jedes Listenobjekt können Sie diesen Code zum Konvertieren in ein XML-Layout verwenden. KeyFather ist Ihr Haupt-Tag und KeySon ist der Startpunkt Ihrer 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
quelle