简体   繁体   中英

De-serialize XML string of different types

I want to deserialize my XML string with different types, the method will have string as input parameter and it will accept 5 types of XML string.

Currently my plan is to choose the class to deserialize the XML String based on the string.StartsWith method to find the type.

Is there any better way to find the type of class for deserialization?

My first recommendation would be to allow the user to select the type when they enter the input so that you don't have to read the string to find the type.

However, if you really, really wanted to, you could do something like this. For the purpose of testing I serialized a class called MyClass . I'm all creative.

var input = @"<MyClass xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""><MyString>Scott</MyString></MyClass>";

var xml = new XmlDocument();
xml.LoadXml(input);
//xml could be null
//Get the tag name of the root element which is
//the name of the serialized type.
var typeName = xml.DocumentElement.Name;
//Try to create a type from that root element's name.
var type = Type.GetType(typeName);
//If it doesn't match a type then it will be null.
if (type != null)
{
    //create an XmlSerializer for that type and deserialize the string.
    var serializer = new XmlSerializer(type);
    using (var sr = new StringReader(input))
    {
        var deserialized = serializer.Deserialize(sr);
    }
}

That will do what you've specified. But now just as you started with an input string which could be serialization of a few possible classes, now you've got an object ( deserialized ) which is also untyped, so I'm not quite sure what you'd do with it next.

If you are asking if there is an elegant way to infer the c# type based on the string, then my answer is 'not really'. You will have to use your favorite mechanism to inspect the input string to infer the type from the string contents.

Or simply not care about what 'type' the input is and use xpath on an xmldocument to do your work.

My favorite c# class type detection mechanism would look something like this:

internal class Converter
{
    public T CovertXML<T>(string XMLString) where T:class
    {
        if (XMLString.ToLower().Contains(typeof(Type1).GetType().Name.ToLower()))
        {
            return XMLString.Deseralize<Type1>() as T;
        }
        //..etc etc.
        return null;
    }
}
internal class Type1
{
}
public static class StringExtensionMethods
{
     public static T Deseralize<T>(this string Instance)
    {
        System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(typeof(T));
        using (System.IO.StringReader sr = new System.IO.StringReader(Instance))
            return (T)ser.Deserialize(sr);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM