C# 反序列化错误:XML元素';名称';从名称空间'';已存在于当前作用域中

C# 反序列化错误:XML元素';名称';从名称空间'';已存在于当前作用域中,c#,xml,serialization,xml-serialization,C#,Xml,Serialization,Xml Serialization,这是我第一次使用XML序列化,经过两天的尝试解决这个问题,这让我非常恼火 当反序列化开始时,我会出现以下错误: The XML element 'name' from namespace '' is already present in the current scope. Use XML attributes to specify another XML name or namespace for the element. 错误发生在我的代码中的这一行: Album album = (Alb

这是我第一次使用XML序列化,经过两天的尝试解决这个问题,这让我非常恼火

当反序列化开始时,我会出现以下错误:

The XML element 'name' from namespace '' is already present in the current scope. Use XML attributes to specify another XML name or namespace for the element.
错误发生在我的代码中的这一行:

Album album = (Album)serializer.Deserialize(reader);
我不知道为什么。没有dup“name”节点,所以我不明白。这是从第三方REST API的HttpWebResponse接收的XML文档

以下是完整的代码:

我的唱片集类(我要反序列化的类型):

我的序列化程序类

    public class Serializer
    {
        public static Album CreateAlbumFromXMLDoc(XmlDocument doc)
        {
            // Create an instance of a serializer
            var serializer = new XmlSerializer(typeof(Album));
            var reader = new StringReader(doc.ToString());

            // Deserialize the Xml Object and cast to type Album
            Album album = (Album)serializer.Deserialize(reader);

            return album;
        }
    }
public static XmlDocument GetResponseXmlDocument(HttpWebResponse response)
        {
            Stream dataStream = null; // stream from WebResponse
            XmlDocument doc = new XmlDocument();

            if (doc == null)
            {
                throw new NullReferenceException("The web reponse was null");
            }

            // Get the response stream so we can read the body of the response
            dataStream = response.GetResponseStream();

            // Open the stream using a StreamReader for easy access
            StreamReader reader = new StreamReader(dataStream);

            // Load response into string variable so that we can then load into an XML doc
            string responseString = reader.ReadToEnd();

            // Create an XML document & load it with the response data
            doc.LoadXml(responseString);

            // Final XML document that represents the response
            return doc;
        }
我尝试反序列化的XML(从在VS中调试时传递到CreateAlbumFromXMLDoc方法的XML文档对象复制):

错误发生在我的代码中的这一行:GetAlbumsResponse album=(GetAlbumsResponse)serializer.Deserialize(reader)

如何将响应转换为XmL文档

    public class Serializer
    {
        public static Album CreateAlbumFromXMLDoc(XmlDocument doc)
        {
            // Create an instance of a serializer
            var serializer = new XmlSerializer(typeof(Album));
            var reader = new StringReader(doc.ToString());

            // Deserialize the Xml Object and cast to type Album
            Album album = (Album)serializer.Deserialize(reader);

            return album;
        }
    }
public static XmlDocument GetResponseXmlDocument(HttpWebResponse response)
        {
            Stream dataStream = null; // stream from WebResponse
            XmlDocument doc = new XmlDocument();

            if (doc == null)
            {
                throw new NullReferenceException("The web reponse was null");
            }

            // Get the response stream so we can read the body of the response
            dataStream = response.GetResponseStream();

            // Open the stream using a StreamReader for easy access
            StreamReader reader = new StreamReader(dataStream);

            // Load response into string variable so that we can then load into an XML doc
            string responseString = reader.ReadToEnd();

            // Create an XML document & load it with the response data
            doc.LoadXml(responseString);

            // Final XML document that represents the response
            return doc;
        }
我的专辑类和根级别类(感谢Marc的帮助。我现在就知道了):
namespace xxx.Entities
{
[可序列化,XmlRoot(“照片\u获取相册\u响应”)]
公共类GetAlbumsResponse
{
[XmlElement(“相册”)]
公共列表相册{get;set;}
[XmlAttribute(“列表”)]
公共布尔岛列表{get;set;}
}
公开课相册
{
#区域构造函数
公共相册()
{
}
#端区
#区域元素常数
/// 
///Constants类以消除对魔术字符串(硬编码字符串)的使用
/// 
公共静态类ElementConstants
{
public const string aID=“aID”;
public const string Owner=“Owner”;
public const string AlbumName=“name”;
public const string CoverPhotoID=“cover\u pid”;
public const string CreateDate=“created”;
公共常量字符串LastModifiedDate=“已修改”;
public const string Description=“Description”;
public const string Location=“Location”;
public const string AlbumURL=“link”;
public const string Size=“Size”;
public const string Visible=“Visible”;
}
#endregion元素常量
#区域公共财产
[xmlement(ElementName=ElementConstants.aID,DataType=“string”)]
公共字符串AlbumID{get;set;}
[XmlElement(ElementName=ElementConstants.CoverPhotoID,DataType=“int”)]
公共Int32 CoverPhotoID{get;set;}
[xmlement(ElementName=ElementConstants.Owner,DataType=“string”)]
公共字符串所有者{get;set;}
[XmlElement(ElementName=ElementConstants.AlbumName,DataType=“string”)]
公共字符串名称{get;set;}
已创建公共字符串{get;set;}
修改的公共日期时间{get;set;}
[XmlElement(ElementName=ElementConstants.Description,DataType=“string”)]
公共字符串说明{get;set;}
[xmlement(ElementName=ElementConstants.Location,DataType=“string”)]
公共字符串位置{get;set;}
[XmlElement(ElementName=ElementConstants.AlbumURL,DataType=“string”)]
公共字符串链接{get;set;}
公共字符串大小{get;set;}
[XmlElement(ElementName=ElementConstants.Visible,DataType=“string”)]
公共字符串可见{get;set;}
#端区
}
}
我的序列化程序类:
namespace xxx.Utilities
{
公共类序列化程序
{
公共静态列表CreateAlbumFromXMLDoc(XmlDocument doc)
{
//创建序列化程序的实例
var serializer=新的XmlSerializer(typeof(Album));
var reader=newstringreader(doc.ToString());
//反序列化Xml对象并强制转换为类型Album
GetAlbumsResponse album=(GetAlbumsResponse)序列化程序。反序列化(读取器);
返回相册。相册;
}
}
}
我正在尝试反序列化的真正传入XML(是的,它确实有xmlns):

7321990241086938677
7031990241087042549
1124262814
专辑测试1
1233469624
1233469942
我们的旅行
加利福尼亚州
http://www.example.com/album.php?aid=7733&id=1124262814
48
朋友
231990241086936240
7042330241087005994
1124262814
专辑测试2
1230437805
1233460690
http://www.example.com/album.php?aid=5296&id=1124262814
34
每个人
70319423341086937544
7032390241087026027
1124262814
专辑测试3
1231984989
1233460349
http://www.example.com/album.php?aid=6600&id=1124262814
3.
朋友


Microsoft针对您的问题发出了一个警告

是-相册绝对不是XML中的根节点

我建议您创建一个包含相册列表的GetAlbumsResponse类,并将反序列化代码移动到包装器类

基本上,从相册类定义中删除根元素,然后:

  [XmlRoot (ElementName="GetAlbums_response")]
public class GetAlbumsResponse
{
    #region Constructors

    public GetAlbumsResponse()
    {

    }

    #endregion



    [XmlArray(ElementName="album")]
    public List<Album> Albums{get;set;}

    ... deserialization code...
[XmlRoot(ElementName=“GetAlbums\u响应”)]
公共类GetAlbumsResponse
{
#区域构造函数
公共GetAlbumsResponse()
{
}
#端区
[XmlArray(ElementName=“album”)]
公共列表相册{get;set;}
…反序列化代码。。。

}

好-我编写了一个示例。我看了一下Facebook API,下面是一个完整的工作示例。 试试这个:

[XmlRoot("photos_getAlbums_response", Namespace="http://api.facebook.com/1.0/")]
public class GetAlbumsResponse
{
    public GetAlbumsResponse() 
    {    
    }

    [XmlElement("album")]
    public List<Album> Albums { get; set; }
}

public class Album
{
    [XmlElement("aid")]
    public long Aid{get;set;}

    [XmlElement("cover_pid")]
    public long CoverPid{get;set;}

    [XmlElement("owner")]
    public long Owner{get;set;}

    [XmlElement("name")]
    public string Name{get;set;}

    [XmlElement("created")]
    public long Created{get;set;}

    [XmlElement("modified")]
    public long Modified{get;set;}

    [XmlElement("description")]
    public string Description{get;set;}

    [XmlElement("location")]
    public string Location{get;set;}

    [XmlElement("link")]
    public string Link{get;set;}

    [XmlElement("size")]
    public int Size{get;set;}

    [XmlElement("visible")]
    public string Visible{get;set;}

    public Album()
    {}
}

class XmlUtils
{
    public static T DeserializeFromXml<T>(string xml)
    {
        T result;
        XmlSerializer ser = new XmlSerializer(typeof(T));
        using (TextReader tr = new StringReader(xml))
        {
            result = (T)ser.Deserialize(tr);
        }
        return result;
    }
}
[XmlRoot(“照片”\u getAlbums\u响应”,名称空间=”http://api.facebook.com/1.0/")]
公共类GetAlbumsResponse
{
公共GetAlbumsResponse()
{    
}
[XmlElement(“相册”)]
公共列表相册{get;set;}
}
公开课相册
{
[XmlElement(“aid”)]
公共长期援助{get;set;}
[XmlElement(“封面
namespace xxx.Utilities
{
    public class Serializer
    {
        public static List<Album> CreateAlbumFromXMLDoc(XmlDocument doc)
        {
            // Create an instance of a serializer
            var serializer = new XmlSerializer(typeof(Album));
            var reader = new StringReader(doc.ToString());

            // Deserialize the Xml Object and cast to type Album
            GetAlbumsResponse album = (GetAlbumsResponse)serializer.Deserialize(reader);

            return album.Albums;
        }
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<photos_GetAlbums_response xmlns="http://api.example.com/1.0/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://api.example.com/1.0/ http://api.example.com/1.0/xxx.xsd" list="true">
  <album>
    <aid>7321990241086938677</aid>
    <cover_pid>7031990241087042549</cover_pid>
    <owner>1124262814</owner>
    <name>Album Test 1</name>
    <created>1233469624</created>
    <modified>1233469942</modified>
    <description>Our trip</description>
    <location>CA</location>
    <link>http://www.example.com/album.php?aid=7733&id=1124262814</link>
    <size>48</size>
    <visible>friends</visible>
  </album>
  <album>
    <aid>231990241086936240</aid>
    <cover_pid>7042330241087005994</cover_pid>
    <owner>1124262814</owner>
    <name>Album Test 2</name>
    <created>1230437805</created>
    <modified>1233460690</modified>
    <description />
    <location />
    <link>http://www.example.com/album.php?aid=5296&id=1124262814</link>
    <size>34</size>
    <visible>everyone</visible>
  </album>
  <album>
    <aid>70319423341086937544</aid>
    <cover_pid>7032390241087026027</cover_pid>
    <owner>1124262814</owner>
    <name>Album Test 3</name>
    <created>1231984989</created>
    <modified>1233460349</modified>
    <description />
    <location />
    <link>http://www.example.com/album.php?aid=6600&id=1124262814</link>
    <size>3</size>
    <visible>friends</visible>
  </album>
</photos_GetAlbums_response>
  [XmlRoot (ElementName="GetAlbums_response")]
public class GetAlbumsResponse
{
    #region Constructors

    public GetAlbumsResponse()
    {

    }

    #endregion



    [XmlArray(ElementName="album")]
    public List<Album> Albums{get;set;}

    ... deserialization code...
[XmlRoot("photos_getAlbums_response", Namespace="http://api.facebook.com/1.0/")]
public class GetAlbumsResponse
{
    public GetAlbumsResponse() 
    {    
    }

    [XmlElement("album")]
    public List<Album> Albums { get; set; }
}

public class Album
{
    [XmlElement("aid")]
    public long Aid{get;set;}

    [XmlElement("cover_pid")]
    public long CoverPid{get;set;}

    [XmlElement("owner")]
    public long Owner{get;set;}

    [XmlElement("name")]
    public string Name{get;set;}

    [XmlElement("created")]
    public long Created{get;set;}

    [XmlElement("modified")]
    public long Modified{get;set;}

    [XmlElement("description")]
    public string Description{get;set;}

    [XmlElement("location")]
    public string Location{get;set;}

    [XmlElement("link")]
    public string Link{get;set;}

    [XmlElement("size")]
    public int Size{get;set;}

    [XmlElement("visible")]
    public string Visible{get;set;}

    public Album()
    {}
}

class XmlUtils
{
    public static T DeserializeFromXml<T>(string xml)
    {
        T result;
        XmlSerializer ser = new XmlSerializer(typeof(T));
        using (TextReader tr = new StringReader(xml))
        {
            result = (T)ser.Deserialize(tr);
        }
        return result;
    }
}
 GetAlbumsResponse response = XmlUtils.DeserializeFromXml<GetAlbumsResponse>(xmlResponseString);
    [XmlElement (ElementName = ElementConstants.AlbumName, DataType = "string")]
    public string AlbumID { get; set; }
...
    [XmlElement(ElementName = ElementConstants.AlbumName, DataType = "string")]
    public string AlbumName { get; set; }
xsd foo.xml
xsd foo.xsd /classes
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

static class Program
{
    const string xml = @"<?xml version=""1.0"" encoding=""UTF-8""?>
<photos_GetAlbums_response
    xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""
    xsi:schemaLocation=""http://api.example.com/1.0/ http://api.example.com/1.0/xxx.xsd""
    list=""true"">
<album>
 <aid>3231990241086938677</aid>
 <cover_pid>7031990241087042549</cover_pid>
 <owner>1337262814</owner>
 <name>LA</name>
 <created>1233469624</created>
 <modified>1233469942</modified>
 <description>trip to LA</description>
 <location>CA</location>
 <link>http://www.example.com/album.php?aid=7333&amp;id=1337262814</link>
 <size>48</size>
 <visible>friends</visible>
 </album>
<album>
 <aid>7031990241086936240</aid>
 <cover_pid>7031990241087005994</cover_pid>
 <owner>1337262814</owner>
 <name>Wall Photos</name>
 <created>1230437805</created>
 <modified>1233460690</modified>
 <description/>
 <location/>
 <link>http://www.example.com/album.php?aid=3296&amp;id=1337262814</link>
 <size>34</size>
 <visible>everyone</visible>
 </album>
<album>
 <aid>7031990241086937544</aid>
 <cover_pid>7031990241087026027</cover_pid>
 <owner>1337262814</owner>
 <name>Mobile Uploads</name>
 <created>1231984989</created>
 <modified>1233460349</modified>
 <description/>
 <location/>
 <link>http://www.example.com/album.php?aid=6300&amp;id=1337262814</link>
 <size>3</size>
 <visible>friends</visible>
 </album>
<album>
 <aid>7031990241086936188</aid>
 <cover_pid>7031990241087005114</cover_pid>
 <owner>1337262814</owner>
 <name>Christmas 2008</name>
 <created>1230361978</created>
 <modified>1230362306</modified>
 <description>My Album</description>
 <location/>
 <link>http://www.example.com/album.php?aid=5234&amp;id=1337262814</link>
 <size>50</size>
 <visible>friends</visible>
 </album>
<album>
 <aid>7031990241086935881</aid>
 <cover_pid>7031990241087001093</cover_pid>
 <owner>1637262814</owner>
 <name>Hock</name>
 <created>1229889219</created>
 <modified>1229889235</modified>
 <description>Misc Pics</description>
 <location/>
 <link>http://www.example.com/album.php?aid=4937&amp;id=1637262814</link>
 <size>1</size>
 <visible>friends-of-friends</visible>
 </album>
<album>
 <aid>7031990241086935541</aid>
 <cover_pid>7031990241086996817</cover_pid>
 <owner>1637262814</owner>
 <name>Test Album 2 (for work)</name>
 <created>1229460455</created>
 <modified>1229460475</modified>
 <description>this is a test album</description>
 <location/>
 <link>http://www.example.com/album.php?aid=4547&amp;id=1637262814</link>
 <size>1</size>
 <visible>everyone</visible>
 </album>
<album>
 <aid>7031990241086935537</aid>
 <cover_pid>7031990241086996795</cover_pid>
 <owner>1637262814</owner>
 <name>Test Album (for work)</name>
 <created>1229459168</created>
 <modified>1229459185</modified>
 <description>Testing for work</description>
 <location/>
 <link>http://www.example.com/album.php?aid=4493&amp;id=1637262814</link>
 <size>1</size>
 <visible>friends</visible>
 </album>
 </photos_GetAlbums_response>";
    static void Main()
    {
        XmlSerializer ser = new XmlSerializer(typeof(GetAlbumsResponse));
        GetAlbumsResponse response;
        using (StringReader reader = new StringReader(xml))
        {
            response = (GetAlbumsResponse)ser.Deserialize(reader);
        }

    }
}

[Serializable, XmlRoot("photos_GetAlbums_response")]
public class GetAlbumsResponse
{
    [XmlElement("album")]
    public List<Album> Albums {get;set;}

    [XmlAttribute("list")]
    public bool IsList { get; set; }
}
public enum AlbumVisibility
{
    [XmlEnum("")]
    None,
    [XmlEnum("friends")]
    Friends,
    [XmlEnum("friends-of-friends")]
    FriendsOfFriends,
    [XmlEnum("everyone")]
    Everyone

}
[Serializable]
public class Album
{
    static readonly DateTime epoch = new DateTime(1970, 1, 1);
    static long SerializeDateTime(DateTime value)
    {
        return (long)((value - epoch).TotalSeconds);
    }
    static DateTime DeserializeDateTime(long value)
    {
        return epoch.AddSeconds(value);
    }
    [XmlElement("aid")]
    public long AlbumID { get; set; }

    [XmlElement("cover_pid")]
    public long CoverPhotoID { get; set; }

    [XmlElement("owner")]
    public long Owner { get; set; }

    [XmlElement("name")]
    public string AlbumName { get; set; }

    [XmlIgnore]
    public DateTime CreateDate { get; set; }

    [XmlElement("created"), Browsable(false)]
    [EditorBrowsable(EditorBrowsableState.Never)]
    public long CreateDateInt64 {
        get {return SerializeDateTime(CreateDate);}
        set {CreateDate = DeserializeDateTime(value);}
    }

    [XmlIgnore]
    public DateTime LastModifiedDate { get; set; }

    [XmlElement("modified"), Browsable(false)]
    [EditorBrowsable(EditorBrowsableState.Never)]
    public long LastModifiedDateInt64
    {
        get { return SerializeDateTime(LastModifiedDate); }
        set { LastModifiedDate = DeserializeDateTime(value); }
    }

    [XmlElement("description")]
    public string Description { get; set; }

    [XmlElement("location")]
    public string Location { get; set; }

    [XmlElement("link")]
    public string Link { get; set; }

    [XmlElement("size")]
    public int Size { get; set; }

    [XmlElement("visible")]
    public AlbumVisibility Visibility { get; set; }
}
<Album><photos_GetAlbums_response>
<Album>
   <photos_GetAlbums_response>
      <Album>
         <photos_GetAlbums_response> ....
[Serializable, XmlRoot("photos_GetAlbums_response",
    Namespace="http://api.example.com/1.0/")]
public class GetAlbumsResponse { /* code as before */ }

[Serializable, XmlType(Namespace="http://api.example.com/1.0/")]
public class Album { /* code as before */ }
string fixedXml = xml.Replace("&", "&amp;");
[XmlElement("aid")]
public string AlbumID { get; set; }

[XmlElement("cover_pid")]
public string CoverPhotoID { get; set; }

[XmlElement("owner")]
public string Owner { get; set; }
    <Root>
       <ArrayNode>
         <SubnodeType1>...</SubnodeType1>
         <SubnodeType1>...</SubnodeType1>
       </ArrayNode>
    </Root>
Or
    <Root>
       <ArrayNode>
         <SubnodeType2>...</SubnodeType2>
         <SubnodeType2>...</SubnodeType2>
       </ArrayNode>
    </Root>
[XmlRoot(Namespace = "", ElementName = "Root")]
public class Root
{
    [XmlArray(ElementName = "ArrayNode", Namespace = "", IsNullable = false, Order = 1)]
    [XmlArrayItem("SubnodeType1")]
    public List<SubnodeType1> SubnodeType1 { get; set; }
    [XmlArray(ElementName = "ArrayNode", Namespace = "", IsNullable = false, Order = 2)]
    [XmlArrayItem("SubnodeType2")]
    public List<SubnodeType2> SubnodeType2 { get; set; }
}