Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# xsi:反序列化XML时的类型问题_C#_Xml - Fatal编程技术网

C# xsi:反序列化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声明,以及必须从类和定义的角度做些什么才能使序列化/反序列化工作。我正在尝试反序列化以下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</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
{}