C# xsi:反序列化XML时的类型问题
请原谅我不熟悉XML声明,以及必须从类和定义的角度做些什么才能使序列化/反序列化工作。我正在尝试反序列化以下XML:C# xsi:反序列化XML时的类型问题,c#,xml,C#,Xml,请原谅我不熟悉XML声明,以及必须从类和定义的角度做些什么才能使序列化/反序列化工作。我正在尝试反序列化以下XML: <?xml version="1.0" encoding="UTF-8"?> <AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <Owner> <ID>946a0786-3840-4007-afe1-76f138a3d31c&
<?xml version="1.0" encoding="UTF-8"?>
<AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Owner>
<ID>946a0786-3840-4007-afe1-76f138a3d31c</ID>
</Owner>
<AccessControlList>
<Grant>
<Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
<ID>946a0786-3840-4007-afe1-76f138a3d31c</ID>
</Grantee>
<Permission>FULL_CONTROL</Permission>
</Grant>
</AccessControlList>
</AccessControlPolicy>
946a0786-3840-4007-afe1-76f138a3d31c
946a0786-3840-4007-afe1-76f138a3d31c
完全控制
引发以下异常:
The specified type was not recognized: name='CanonicalUser', namespace='http://s3.amazonaws.com/doc/2006-03-01/', at <Grantee xmlns='http://s3.amazonaws.com/doc/2006-03-01/'>.
无法识别指定的类型:name='CanonicalUser',namespace='2'http://s3.amazonaws.com/doc/2006-03-01/",在。
我将代码缩减为以下内容,以便单独复制:
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml.Serialization;
namespace sandbox
{
public partial class Program
{
static void Main(string[] args)
{
string xml =
"<AccessControlPolicy xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><Owner><ID>946a0786-3840-4007-afe1-76f138a3d31c</ID></Owner><AccessControlList><Grant><Grantee xsi:type=\"CanonicalUser\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><ID>946a0786-3840-4007-afe1-76f138a3d31c</ID></Grantee><Permission>FULL_CONTROL</Permission></Grant><Grant><Grantee xsi:type=\"CanonicalUser\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><ID>946a0786-3840-4007-afe1-76f138a3d31c</ID></Grantee><Permission>READ</Permission></Grant><Grant><Grantee xsi:type=\"CanonicalUser\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><ID>946a0786-3840-4007-afe1-76f138a3d31c</ID></Grantee><Permission>WRITE</Permission></Grant><Grant><Grantee xsi:type=\"CanonicalUser\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><ID>946a0786-3840-4007-afe1-76f138a3d31c</ID></Grantee><Permission>READ_ACP</Permission></Grant><Grant><Grantee xsi:type=\"CanonicalUser\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><ID>946a0786-3840-4007-afe1-76f138a3d31c</ID></Grantee><Permission>WRITE_ACP</Permission></Grant></AccessControlList></AccessControlPolicy>";
try
{
AccessControlPolicy acp = DeserializeXml<AccessControlPolicy>(xml);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
Console.WriteLine(e.Message);
}
Console.ReadLine();
}
public static T DeserializeXml<T>(string xml)
{
XmlSerializer xmls = new XmlSerializer(typeof(T));
using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
{
return (T)xmls.Deserialize(ms);
}
}
}
[XmlRoot(ElementName = "AccessControlPolicy", Namespace = "http://s3.amazonaws.com/doc/2006-03-01/", IsNullable = true)]
public class AccessControlPolicy
{
[XmlElement(ElementName = "Owner", Namespace = "http://s3.amazonaws.com/doc/2006-03-01/", IsNullable = true)]
public Owner Owner { get; set; }
[XmlElement(ElementName = "AccessControlList", Namespace = "http://s3.amazonaws.com/doc/2006-03-01/", IsNullable = true)]
public AccessControlList AccessControlList { get; set; }
}
[XmlRoot(ElementName = "AccessControlList", Namespace = "http://s3.amazonaws.com/doc/2006-03-01/", IsNullable = true)]
public class AccessControlList
{
[XmlElement(ElementName = "Grant", Namespace = "http://s3.amazonaws.com/doc/2006-03-01/", IsNullable = true)]
public List<Grant> Grant { get; set; }
}
[XmlRoot(ElementName = "Grant", Namespace = "http://s3.amazonaws.com/doc/2006-03-01/", IsNullable = true)]
public class Grant
{
[XmlElement(ElementName = "Grantee", Namespace = "http://s3.amazonaws.com/doc/2006-03-01/", IsNullable = true)]
public Grantee Grantee { get; set; }
[XmlElement(ElementName = "Permission", Namespace = "http://s3.amazonaws.com/doc/2006-03-01/", IsNullable = true)]
public string Permission { get; set; }
}
[XmlRoot(ElementName = "Grantee", Namespace = "http://s3.amazonaws.com/doc/2006-03-01/", IsNullable = true)]
public class Grantee
{
[XmlElement(ElementName = "ID", Namespace = "http://s3.amazonaws.com/doc/2006-03-01/", IsNullable = true)]
public string ID { get; set; }
[XmlElement(ElementName = "URI", Namespace = "http://s3.amazonaws.com/doc/2006-03-01/", IsNullable = true)]
public string URI { get; set; }
[XmlElement(ElementName = "DisplayName", Namespace = "http://s3.amazonaws.com/doc/2006-03-01/", IsNullable = true)]
public string DisplayName { get; set; }
[XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2000/xmlns/")]
public string Xsi { get; set; }
[XmlAttribute(AttributeName = "type", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public string Type { get; set; }
}
[XmlRoot(ElementName = "Owner", Namespace = "http://s3.amazonaws.com/doc/2006-03-01/", IsNullable = true)]
public class Owner
{
[XmlElement(ElementName = "ID", Namespace = "http://s3.amazonaws.com/doc/2006-03-01/", IsNullable = true)]
public string ID { get; set; }
[XmlElement(ElementName = "DisplayName", Namespace = "http://s3.amazonaws.com/doc/2006-03-01/", IsNullable = true)]
public string DisplayName { get; set; }
}
}
使用系统;
使用System.Collections.Generic;
使用System.IO;
使用系统文本;
使用System.Xml.Serialization;
名称空间沙盒
{
公共部分课程
{
静态void Main(字符串[]参数)
{
字符串xml=
“946a0786-3840-4007-afe1-76f138a3d31c946a0786-3840-4007-afe1-76F138A3D31全控946a0786-3840-4007-afe1-76f138a3d31cREAD946a0786-3840-4007-afe1-76F138A3D31书面946a0786-3840-4007-afe1-76F138A3D31书面ACP946a0786-3840-4007-76F138A3D31书面ACP”;
尝试
{
AccessControlPolicy acp=反序列化xml(xml);
}
捕获(例外e)
{
Console.WriteLine(如ToString());
控制台写入线(e.Message);
}
Console.ReadLine();
}
公共静态T反序列化xml(字符串xml)
{
XmlSerializer xmls=新的XmlSerializer(typeof(T));
使用(MemoryStream ms=newmemoryStream(Encoding.UTF8.GetBytes(xml)))
{
返回(T)xmls.反序列化(ms);
}
}
}
[XmlRoot(ElementName=“AccessControlPolicy”,命名空间=”http://s3.amazonaws.com/doc/2006-03-01/“,IsNullable=true)]
公共类访问控制策略
{
[XmlElement(ElementName=“所有者”,命名空间=”http://s3.amazonaws.com/doc/2006-03-01/“,IsNullable=true)]
公共所有者{get;set;}
[XmlElement(ElementName=“AccessControlList”,命名空间=”http://s3.amazonaws.com/doc/2006-03-01/“,IsNullable=true)]
公共访问控制列表访问控制列表{get;set;}
}
[XmlRoot(ElementName=“AccessControlList”,命名空间=”http://s3.amazonaws.com/doc/2006-03-01/“,IsNullable=true)]
公共类访问控制器
{
[XmlElement(ElementName=“Grant”,命名空间=”http://s3.amazonaws.com/doc/2006-03-01/“,IsNullable=true)]
公共列表授予{get;set;}
}
[XmlRoot(ElementName=“Grant”,命名空间=”http://s3.amazonaws.com/doc/2006-03-01/“,IsNullable=true)]
公费助学金
{
[XmlElement(ElementName=“Grantee”,命名空间=”http://s3.amazonaws.com/doc/2006-03-01/“,IsNullable=true)]
公共受让人{get;set;}
[XmlElement(ElementName=“权限”,命名空间=”http://s3.amazonaws.com/doc/2006-03-01/“,IsNullable=true)]
公共字符串权限{get;set;}
}
[XmlRoot(ElementName=“Grantee”,命名空间=”http://s3.amazonaws.com/doc/2006-03-01/“,IsNullable=true)]
公共级承授人
{
[XmlElement(ElementName=“ID”,命名空间=”http://s3.amazonaws.com/doc/2006-03-01/“,IsNullable=true)]
公共字符串ID{get;set;}
[XmlElement(ElementName=“URI”,命名空间=”http://s3.amazonaws.com/doc/2006-03-01/“,IsNullable=true)]
公共字符串URI{get;set;}
[XmlElement(ElementName=“DisplayName”,命名空间=”http://s3.amazonaws.com/doc/2006-03-01/“,IsNullable=true)]
公共字符串DisplayName{get;set;}
[XmlAttribute(AttributeName=“xsi”,命名空间=”http://www.w3.org/2000/xmlns/")]
公共字符串Xsi{get;set;}
[XmlAttribute(AttributeName=“type”,命名空间=”http://www.w3.org/2001/XMLSchema-instance")]
公共字符串类型{get;set;}
}
[XmlRoot(ElementName=“所有者”,命名空间=”http://s3.amazonaws.com/doc/2006-03-01/“,IsNullable=true)]
公共类所有者
{
[XmlElement(ElementName=“ID”,命名空间=”http://s3.amazonaws.com/doc/2006-03-01/“,IsNullable=true)]
公共字符串ID{get;set;}
[XmlElement(ElementName=“DisplayName”,命名空间=”http://s3.amazonaws.com/doc/2006-03-01/“,IsNullable=true)]
公共字符串DisplayName{get;set;}
}
}
将您的类授权重命名为CanonicalUser
[XmlRoot(ElementName = "AccessControlList", Namespace = "http://s3.amazonaws.com/doc/2006-03-01/", IsNullable = true)]
public class AccessControlList
{
[XmlElement(ElementName = "Grant", Namespace = "http://s3.amazonaws.com/doc/2006-03-01/", IsNullable = true)]
public List<CanonicalUser> Grant { get; set; }
}
[XmlRoot(ElementName = "Grant", Namespace = "http://s3.amazonaws.com/doc/2006-03-01/", IsNullable = true)]
public class CanonicalUser
{
[XmlElement(ElementName = "Grantee", Namespace = "http://s3.amazonaws.com/doc/2006-03-01/", IsNullable = true)]
public Grantee Grantee { get; set; }
[XmlElement(ElementName = "Permission", Namespace = "http://s3.amazonaws.com/doc/2006-03-01/", IsNullable = true)]
public string Permission { get; set; }
}
[XmlRoot(ElementName=“AccessControlList”,命名空间=”http://s3.amazonaws.com/doc/2006-03-01/“,IsNullable=true)]
公共类访问控制器
{
[XmlElement(ElementName=“Grant”,命名空间=”http://s3.amazonaws.com/doc/2006-03-01/“,IsNullable=true)]
公共列表授予{get;set;}
}
[XmlRoot(ElementName=“Grant”,命名空间=”http://s3.amazonaws.com/doc/2006-03-01/“,IsNullable=true)]
公共类CanonicalUser
{
[XmlElement(ElementName=“Grantee”,命名空间=”http://s3.amazonaws.com/doc/2006-03-01/“,IsNullable=true)]
公共受让人{get;set;}
[XmlElement(ElementName=“权限”,命名空间=”http://s3.amazonaws.com/doc/2006-03-01/“,IsNullable=true)]
公共字符串权限{get;set;}
}
XmlSerializer使用xsi:type
说明符解析反序列化的目标类
因为您的目标类
被命名为受让人
,所以您必须使用XmlType
属性来修饰它,将CanonicalUser
指定为类型名
[XmlType(TypeName= "CanonicalUser")]
public class Grantee
注意,您可以减少应用于类的xml名称空间
,如下所示
[XmlRoot(ElementName = "AccessControlPolicy", Namespace = "http://s3.amazonaws.com/doc/2006-03-01/")]
public class AccessControlPolicy
{
[XmlElement(ElementName = "Owner", IsNullable = true)]
public Owner Owner { get; set; }
[XmlElement(ElementName = "AccessControlList", IsNullable = true)]
public AccessControlList AccessControlList { get; set; }
}
更新 如果要使用不同的
xsi:type
说明符,例如
<Grantee xsi:type="CanonicalUser" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Grantee xsi:type="AnotherUser" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
xml名称空间看起来
public class Grant
{
[XmlElement(ElementName = "Grantee", IsNullable = true)]
public Grantee Grantee { get; set; }
[XmlElement(ElementName = "Permission", IsNullable = true)]
public string Permission { get; set; }
}
[XmlType(TypeName= "CanonicalUser")]
public class Grantee
{
[XmlElement(ElementName = "ID", IsNullable = true)]
public string ID { get; set; }
[XmlElement(ElementName = "URI", IsNullable = true)]
public string URI { get; set; }
[XmlElement(ElementName = "DisplayName", IsNullable = true)]
public string DisplayName { get; set; }
}
public class Owner
{
[XmlElement(ElementName = "ID", IsNullable = true)]
public string ID { get; set; }
[XmlElement(ElementName = "DisplayName", IsNullable = true)]
public string DisplayName { get; set; }
}
<Grantee xsi:type="CanonicalUser" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Grantee xsi:type="AnotherUser" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
[XmlInclude(typeof(CanonicalUser))]
[XmlInclude(typeof(AnotherUser))]
public abstract class Grantee
{
// ...
}
[XmlType(TypeName= "CanonicalUser", Namespace = "http://s3.amazonaws.com/doc/2006-03-01/")]
public class CanonicalUser : Grantee
{}
[XmlType(TypeName = "AnotherUser", Namespace = "http://s3.amazonaws.com/doc/2006-03-01/")]
public class AnotherUser : Grantee
{}