【问题标题】:Deserialization Error: The XML element 'name' from namespace '' is already present in the current scope反序列化错误:命名空间“”中的 XML 元素“名称”已存在于当前范围内
【发布时间】:2010-10-06 02:42:37
【问题描述】:

这是我第一次使用 XML 序列化,在尝试解决此问题 2 天后,这让我绝对疯狂

反序列化开始时出现此错误:

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" 节点,所以我不明白。这是从第 3 方 REST API 的 HttpWebResponse 接收的 XML 文档。

这是完整的代码:

我的专辑类(我要反序列化到的类型):

    public class Album
    {
        #region Constructors

        public Album() 
        { 

        }

        #endregion

        #region ElementConstants

        public static class ElementConstants
        {
            public const string aID = "aid";
            public const string Owner = "owner";
            public const string AlbumName = "name";
            public const string CoverPhotoID = "cover_pid";
            public const string CreateDate = "created";
            public const string LastModifiedDate = "modified";
            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 ElementConstants

        #region Public Properties

        [XmlArray(ElementName = "photos_GetAlbums_response")]
        [XmlArrayItem( "album" )]
        public Album[] Albums { get; set; }

        [XmlElement (ElementName = ElementConstants.AlbumName, DataType = "string")]
        public string AlbumID { get; set; }

        [XmlElement(ElementName = ElementConstants.aID, DataType = "int")]
        public Int32 CoverPhotoID { get; set; }

        [XmlElement(ElementName = ElementConstants.Owner, DataType = "string")]
        public string Owner { get; set; }

        [XmlElement(ElementName = ElementConstants.AlbumName, DataType = "string")]
        public string AlbumName { get; set; }

        [XmlElement(ElementName = ElementConstants.aID, DataType = "DateTime")]
        public DateTime CreateDate { get; set; }

        [XmlElement(ElementName = ElementConstants.LastModifiedDate, DataType = "DateTime")]
        public DateTime LastModifiedDate { get; set; }

        [XmlElement(ElementName = ElementConstants.Description, DataType = "string")]
        public string Description { get; set; }

        [XmlElement(ElementName = ElementConstants.Location, DataType = "string")]
        public string Location { get; set; }

        [XmlElement(ElementName = ElementConstants.AlbumURL, DataType = "string")]
        public string Link { get; set; }

        [XmlElement(ElementName = ElementConstants.Size, DataType = "size")]
        public string Size { get; set; }

        [XmlElement(ElementName = ElementConstants.Visible, DataType = "string")]
        public string Visible { get; set; }

        #endregion
    }

我的序列化程序类

    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;
        }
    }

我试图反序列化的 XML(从在 VS 中调试时传递给 CreateAlbumFromXMLDoc 方法的 Xml Doc 对象复制):

<?xml version="1.0" encoding="UTF-8"?>
<photos_GetAlbums_response 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&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&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&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&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&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&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&id=1637262814</link>
 <size>1</size>
 <visible>friends</visible>
 </album>
 </photos_GetAlbums_response>

附注:只是为了它,我将该 XML 粘贴到 XML Notepad 2007 中,它告诉我:

您的 XML 文档不包含 xml-stylesheet 处理指令。要提供 XSLT 转换,请将以下内容添加到文件顶部并相应地编辑 href 属性:

我不认为这真的意味着它格式不正确或其他任何东西,只是需要注意。

所以..

我的最终目标是明显地通过这个该死的错误,并在我能克服错误后使用上面的代码取回一系列专辑。我还想确保我的代码在尝试使用我的 Album 类中的 Album[] 属性或我可能在这里丢失的任何其他内容时正确检索专辑的数组。我认为它非常接近并且应该可以工作,但事实并非如此。


跟进。从那以后我一直在拔头发。

这是最新的。我暂时没有使用一些东西(来自 Marc),比如 Enum 等。我以后可能会改变它。我还拿出了日期时间的东西,因为它看起来很奇怪,而且我没有在没有错误的情况下出现错误……至少现在还没有。现在的主要问题仍然是我该死的 XML。

我猜它的格式似乎仍然存在问题?除非它掩盖了另一个问题,否则没有线索。这让我发疯了。

我现在在反序列化开始时收到此错误

Data at the root level is invalid. Line 1, position 1.

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

如何将响应写入 XmL 文档

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
{

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

        [XmlAttribute("list")]
        public bool IsList { get; set; }
    }

    public class Album
    {
        #region Constructors

        public Album()
        {

        }

        #endregion

        #region ElementConstants

        /// <summary>
        /// Constants Class to eliminate use of Magic Strings (hard coded strings)
        /// </summary>
        public static class ElementConstants
        {
            public const string aID = "aid";
            public const string Owner = "owner";
            public const string AlbumName = "name";
            public const string CoverPhotoID = "cover_pid";
            public const string CreateDate = "created";
            public const string LastModifiedDate = "modified";
            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 ElementConstants

        #region Public Properties

        [XmlElement (ElementName = ElementConstants.aID, DataType = "string")]
        public string AlbumID { get; set; }

        [XmlElement(ElementName = ElementConstants.CoverPhotoID, DataType = "int")]
        public Int32 CoverPhotoID { get; set; }

        [XmlElement(ElementName = ElementConstants.Owner, DataType = "string")]
        public string Owner { get; set; }

        [XmlElement(ElementName = ElementConstants.AlbumName, DataType = "string")]
        public string AlbumName { get; set; }

        public string Created { get; set; }

        public DateTime Modified { get; set; }

        [XmlElement(ElementName = ElementConstants.Description, DataType = "string")]
        public string Description { get; set; }

        [XmlElement(ElementName = ElementConstants.Location, DataType = "string")]
        public string Location { get; set; }

        [XmlElement(ElementName = ElementConstants.AlbumURL, DataType = "string")]
        public string Link { get; set; }

        public string Size { get; set; }

        [XmlElement(ElementName = ElementConstants.Visible, DataType = "string")]
        public string Visible { get; set; }

        #endregion
    }
}

我的序列化程序类:

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 传入,我正在尝试反序列化(是的,它确实有 xmlns):

<?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>

【问题讨论】:

  • 序列化 XML 中的给定“专辑”标签内是否有多个“名称”标签?

标签: c# xml serialization xml-serialization


【解决方案1】:

就我个人而言,我不会在这里使用常量——它们很难发现错误(而且由于您可能没有重复使用它们,所以不要添加太多)。例如:

    [XmlElement (ElementName = ElementConstants.AlbumName, DataType = "string")]
    public string AlbumID { get; set; }
...
    [XmlElement(ElementName = ElementConstants.AlbumName, DataType = "string")]
    public string AlbumName { get; set; }

我觉得很可疑……

一种更简单的方法是将您想要的 xml 写入文件(例如foo.xml)并使用:

xsd foo.xml
xsd foo.xsd /classes

那就看foo.cs

【讨论】:

  • 我同意,通过 xsd 工具运行它!
  • 马克,还记得为什么这些帖子没有被关闭/删除为重复的吗?
  • 我猜:没有足够的选票......它早于我可以强制解决问题的时间,但我似乎也记得每个人都透露了不同的信息。
【解决方案2】:

我们开始...注意 xml 无效(&amp;amp; 应该是 &amp;amp;;使用未声明的 xsi 命名空间别名)。另请注意,我为可见性添加了一个枚举,添加了将 long 转换为 DateTime 的处理,并添加了包装器类型:

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; }
}

【讨论】:

  • DeserializeDateTime 可以通过使用以下 DateTime 方法之一来完成:ToFileTimeUtc()ToBinary() 或只是简单的DateTime(long)。你的方法(epoch.AddSeconds)有什么更好的吗?我刚刚重用了您对solve my question 的回答的这一部分。很抱歉打扰你这么老的答案:)
  • @HuBeZa - 没有更好,也没有更糟。对于互操作目的可能更熟悉,这就是我选择它的原因
【解决方案3】:

(2 月 8 日)首先,将 xml 视为字符串(用于读取)不会导致错误。

问题在于命名空间(xmlns没有xsi);这不在早期的 xml 中,所以我无法包含它...基本上,您需要告诉序列化程序:

[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 */ }

在这种情况下,命名空间的常量有意义(因为您正在重复使用它)。

如果您显示的 xml 是准确的,那么链接仍然是损坏的,但是...但这可能只是复制/粘贴(即在您知道错误之前不要应用此更改...):您需要 &amp;amp;(不是&amp;)。建议一些“替换”......在最粗略的水平:

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; }

通过这些更改(主要是我的原始代码),它可以工作了。

当然,此时你应该想“我希望我能used xsd”。

【讨论】:

    【解决方案4】:

    是的 - 专辑绝对不是您 XML 中的根节点。

    我建议您创建一个包含专辑列表的 GetAlbumsResponse 类,并将您的反序列化代码移至包装类。

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

      [XmlRoot (ElementName="GetAlbums_response")]
    public class GetAlbumsResponse
    {
        #region Constructors
    
        public GetAlbumsResponse()
        {
    
        }
    
        #endregion
    
    
    
        [XmlArray(ElementName="album")]
        public List<Album> Albums{get;set;}
    
        ... deserialization code...
    

    }

    【讨论】:

    • 谢谢,我是序列化的新手..所以让我试一试。有趣。
    • 我不知道我是否对创建一个获取专辑相关属性并将其推入基本上非专辑类的类感觉良好。嗯,让我再考虑一下。
    • 我的专辑类中实际上有一个构造函数(我没有显示),它接受一个 HttpWebResponse 参数。所以基本上我已经通过接受响应在我的专辑课程中完成了第一部分
    • 我正在我的专辑课程中接受该响应,并在该课程中将其转换为 XmL Doc。所以我在相册类中可以在本地使用它。
    • 我实际上在构造函数中将响应转换为一个 XmlDocument
    【解决方案5】:

    嗯,

    有一个来自 Microsoft 的 link 针对您的问题

    【讨论】:

    • 所以在审查后要求更改架构。好吧,我相信这意味着改变 XML 文档格式。我们不能这样做,我们从第三方 API 获取 XML 文档
    • 等等,没有重复的。每条记录都有一个名称子节点。我不明白。
    • 什么是重复的?这里返回了几张专辑,每张专辑都有一个名称节点......我没有看到重复。
    • @Dimi - 请阅读这篇文章:不要说“点击这里” - w3.org/QA/Tips/noClickHere :)
    【解决方案6】:

    适用于您当前代码的 Xml 如下所示:

    <Album><photos_GetAlbums_response>
    <Album>
       <photos_GetAlbums_response>
          <Album>
             <photos_GetAlbums_response> ....
    

    一个响应,它有一个专辑数组,其中每个专辑都有一个响应,它是一个专辑数组......等等。

    不管怎样,我已经在你的其他问题上帮助了你,甚至不厌其烦地创建了一个完整的工作代码示例。你为什么要为同一个问题创建另一个问题?

    【讨论】:

      【解决方案7】:

      Use System.Xml.XmlDocument to parse the input. 自己编写提取数据的代码不会超过一个小时。

      【讨论】:

        【解决方案8】:

        好的 - 我编写了一个示例。我查看了 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;
            }
        }
        

        现在.. 使用来自 Facebook API 的 xml photos_getAlbums_response,

        你可以这样反序列化:

         GetAlbumsResponse response = XmlUtils.DeserializeFromXml<GetAlbumsResponse>(xmlResponseString);
        

        【讨论】:

        • 谢谢,我很欣赏这个例子。这是真正困扰我的事情。我不想仅仅为了指定专辑之外的根而创建一个类。我的意思是在你的例子中,它是一个裸类,我想把 DeserializeResponseFromXml 放在一个可重用的实用程序类中。
        • 所以基本上我想知道是否有办法将该属性(通用列表)移回我的专辑类中,将 DeserializeResponseFromXml 移动到一个实用程序类,我可以在我的所有类中重用它,并且然后以某种方式处理我的专辑类中的根节点与某处的另一个属性?
        • 我正在处理它..但希望将属性保留在专辑类中...让我尝试一些我猜想的东西...
        • Response 类不是“仅仅为了指定根外部专辑”。您正在从 Xml 反序列化并创建响应的对象表示。但当然,这是你的代码,你可以做任何你喜欢的事情;)。
        • 在我看来,在 Album 类中包含专辑列表是不好的 OO 编程。为什么专辑应该有所有其他专辑的列表?当您生成该列表时,您是否要在列表中的每个对象中设置列表...?
        【解决方案9】:

        这是一个非常古老的线程,但我自己也遇到了同样的问题,我试图在同一个类中以相同的 XmlArray 名称序列化两个不同的列表类型,类似于

            <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; }
        }
        

        希望对其他人有所帮助:)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-03-12
          • 1970-01-01
          • 1970-01-01
          • 2013-05-02
          • 2012-03-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多