这是我第一次使用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);
我不确定为什么.没有重复的"名称"节点,所以我只是没有得到它.这是从第三方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对象中复制):
3231990241086938677 7031990241087042549 1337262814 LA 1233469624 1233469942 trip to LA CA http://www.example.com/album.php?aid=7333&id=133726281448 friends 7031990241086936240 7031990241087005994 1337262814 Wall Photos 1230437805 1233460690 http://www.example.com/album.php?aid=3296&id=1337262814 34 everyone 7031990241086937544 7031990241087026027 1337262814 Mobile Uploads 1231984989 1233460349 http://www.example.com/album.php?aid=6300&id=1337262814 3 friends 7031990241086936188 7031990241087005114 1337262814 Christmas 2008 1230361978 1230362306 My Album http://www.example.com/album.php?aid=5234&id=1337262814 50 friends 7031990241086935881 7031990241087001093 1637262814 Hock 1229889219 1229889235 Misc Pics http://www.example.com/album.php?aid=4937&id=1637262814 1 friends-of-friends 7031990241086935541 7031990241086996817 1637262814 Test Album 2 (for work) 1229460455 1229460475 this is a test album http://www.example.com/album.php?aid=4547&id=1637262814 1 everyone 7031990241086935537 7031990241086996795 1637262814 Test Album (for work) 1229459168 1229459185 Testing for work http://www.example.com/album.php?aid=4493&id=1637262814 1 friends
旁注:为了它的地狱,我将XML粘贴到XML Notepad 2007中,它告诉我:
您的XML文档不包含xml样式表处理指令.要提供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; }
namespace xxx.Entities { [Serializable, XmlRoot("photos_GetAlbums_response")] public class GetAlbumsResponse { [XmlElement("album")] public ListAlbums { get; set; } [XmlAttribute("list")] public bool IsList { get; set; } } public class Album { #region Constructors public Album() { } #endregion #region ElementConstants /// /// Constants Class to eliminate use of Magic Strings (hard coded strings) /// 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 ListCreateAlbumFromXMLDoc(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; } } }
7321990241086938677 7031990241087042549 1124262814 Album Test 1 1233469624 1233469942 Our trip CA http://www.example.com/album.php?aid=7733&id=112426281448 friends 231990241086936240 7042330241087005994 1124262814 Album Test 2 1230437805 1233460690 http://www.example.com/album.php?aid=5296&id=1124262814 34 everyone 70319423341086937544 7032390241087026027 1124262814 Album Test 3 1231984989 1233460349 http://www.example.com/album.php?aid=6600&id=1124262814 3 friends
Marc Gravell.. 5
就个人而言,我不会在这里使用常量 - 它们很难发现错误(因为你可能没有重新使用它们,所以不要添加太多).例如:
[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
.
就个人而言,我不会在这里使用常量 - 它们很难发现错误(因为你可能没有重新使用它们,所以不要添加太多).例如:
[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
.