C# 使用不同的根元素名称反序列化

C# 使用不同的根元素名称反序列化,c#,xml,xml-serialization,xmlserializer,C#,Xml,Xml Serialization,Xmlserializer,下面的示例给出了“[One xmlns=''”不是预期的。”异常 public abstract class BaseClass{ } [XmlRoot("One")] public class ChildOne : BaseClass {} [XmlRoot("Two")] public class ChildTwo : BaseClass { } class Program { private static void Main(string[] args) {

下面的示例给出了“[One xmlns=''”不是预期的。”异常

public abstract class BaseClass{ }

[XmlRoot("One")]
public class ChildOne : BaseClass {}

[XmlRoot("Two")]
public class ChildTwo : BaseClass { }

class Program
{
    private static void Main(string[] args)
    {
        var ser = new XmlSerializer(typeof (BaseClass), new Type[] {typeof (ChildOne), typeof (ChildTwo)});
        var obj1 = ser.Deserialize(new StringReader(@"<?xml version=""1.0""?><One></One>"));
        var obj2 = ser.Deserialize(new StringReader(@"<?xml version=""1.0""?><Two></Two>"));
    }
}
公共抽象类基类{}
[XmlRoot(“一”)]
公共类ChildOne:基类{}
[XmlRoot(“两个”)]
公共类ChildTwo:基类{}
班级计划
{
私有静态void Main(字符串[]args)
{
var ser=newxmlserializer(typeof(BaseClass),new Type[]{typeof(ChildOne),typeof(ChildTwo)});
var obj1=ser.Deserialize(新StringReader(@“”);
var obj2=ser.Deserialize(新的StringReader(@“”);
}
}
我需要反序列化XML(不是由我生成的)。根标记可能有不同的名称,我必须映射到不同的类


另外,我知道有很多这样的问题。我已经研究过了,但我的问题仍然没有解决。

没有围绕我的问题大肆宣传。社区可能会认为这只是一个白痴提出的又一个愚蠢的问题。他们可能是对的。我得自己回答,但要小心:答案可能也很愚蠢

我最后探测了XML的根元素,然后将其映射到一个已知类型,并使用该类型进行反序列化。像这样:

public abstract class BaseClass{ }

[XmlRoot("One")]
public class ChildOne : BaseClass {}

[XmlRoot("Two")]
public class ChildTwo : BaseClass { }

class Program
{
    private static void Main(string[] args)
    {
        var known = new Type[] {typeof (ChildOne), typeof (ChildTwo)};
        var obj1 = Deserialize<BaseClass>(@"<?xml version=""1.0""?><One></One>", known);
        var obj2 = Deserialize<BaseClass>(@"<?xml version=""1.0""?><Two></Two>", known);
    }

    private static T Deserialize<T>(string xml, Type[] knownTypes)
    {
        Type rootType = typeof (T);

        if (knownTypes.Any())
        {
            using (var reader = XmlReader.Create(new StringReader(xml)))
            {
                reader.MoveToContent();

                rootType = (from kt in knownTypes
                        let xmlRoot = kt.GetCustomAttributes<XmlRootAttribute>().FirstOrDefault()
                        where kt.Name == reader.Name || (xmlRoot != null && xmlRoot.ElementName == reader.Name)
                        select kt).FirstOrDefault() ?? typeof(T);
            }
        }

        return (T) new XmlSerializer(rootType, knownTypes).Deserialize(new StringReader(xml));
    }
}
公共抽象类基类{}
[XmlRoot(“一”)]
公共类ChildOne:基类{}
[XmlRoot(“两个”)]
公共类ChildTwo:基类{}
班级计划
{
私有静态void Main(字符串[]args)
{
var known=新类型[]{typeof(ChildOne),typeof(ChildTwo)};
var obj1=反序列化(@“”,已知);
var obj2=反序列化(@“”,已知);
}
私有静态T反序列化(字符串xml,类型[]knownTypes)
{
类型rootType=typeof(T);
if(knownTypes.Any())
{
使用(var reader=XmlReader.Create(newstringreader(xml)))
{
reader.MoveToContent();
rootType=(来自knownTypes中的kt)
设xmlRoot=kt.GetCustomAttributes().FirstOrDefault()
其中kt.Name==reader.Name | |(xmlRoot!=null&&xmlRoot.ElementName==reader.Name)
选择kt).FirstOrDefault()??类型(T);
}
}
返回(T)新的XmlSerializer(rootType,knownTypes)。反序列化(新的StringReader(xml));
}
}

要扩展您的答案,您可以使用一点LinqToXml来解析xml以获得根名称

private T Deserialize<T>(string xml, Type[] knownTypes)
{
    var rootType = knownTypes.FirstOrDefault(t => t.GetCustomAttributes<XmlRootAttribute>()
                                                   .Any(a => a.ElementName == XElement.Parse(xml).Name.LocalName));

    return (T)new XmlSerializer(rootType ?? typeof(T), knownTypes).Deserialize(new StringReader(xml));
}
private T反序列化(字符串xml,类型[]knownTypes)
{
var rootType=knownTypes.FirstOrDefault(t=>t.GetCustomAttributes()
.Any(a=>a.ElementName==XElement.Parse(xml.Name.LocalName));
返回(T)新的XmlSerializer(rootType??typeof(T),knownTypes)。反序列化(新的StringReader(xml));
}

我在找什么!