Я впервые использую сериализацию 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);
Я не уверен, почему. Нет двойного узла "name", поэтому я просто не понимаю. Это документ XML, полученный от HttpWebResponse от стороннего REST API.
Вот полный код:
Класс моего альбома (тип, к которому я десериализуюсь):
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, который я пытаюсь десериализовать (скопированный из объекта Xml Doc, передаваемого в метод CreateAlbumFromXMLDoc при отладке в VS):
<?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. Чтобы обеспечить 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 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>