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 .


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

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.


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

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();
        }
    }
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.