Deserialization error: XML element 'name' from namespace '' is already present in the current scope

This is my first time using XML serialization and it makes me absolutely nuts after 2 days trying to fix this problem.

I get this error when deserialization starts:

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. 

The error in this line in my code is:

 Album album = (Album)serializer.Deserialize(reader); 

I'm not sure why. There is no duplicate "name" node, so I just don't get it. This is an XML document obtained from HttpWebResponse from a third-party REST API.

Here is the full code:

My album class (the type by which I deserialize):

  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 } 

My Serializer class :

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

The XML I'm trying to destroy (copied from an Xml Doc object that is passed to the CreateAlbumFromXMLDoc method when debugging in 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> 

Note: Just hell, I paste this XML into an XML 2007 notepad, it tells me:

The XML document does not contain xml-stylesheet processing instructions. To enable XSLT conversion, add the following to the top of the file and edit the href attribute accordingly:

I do not think that this really means that it is distorted or something like that, but just a note.

So..

My ultimate goal is to get this damn mistake and get an array of albums using my code above as soon as I can get past the error. I also want to make sure my code is correct when trying to restore this album using the Album [] property in my Album class or something else that I might not see here. I think this is pretty close and should work, but it is not.


Follow-up Since then I have been pulling my hair out.

Here is the last one. At the moment I have not used some things (from Mark) like Enum, etc. I could change this later. I also pulled out datetime stuff as it just looked weird and I didn't get any errors on this for now ... at least for now. The main problem now is my damn XML.

Is he still having problems with the format I assume? If this does not cover another problem, he has no idea. It drives me crazy.

Now I get this error when deserialization kicks in :

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

The error in this line is in my code: GetAlbumsResponse album = (GetAlbumsResponse) serializer.Deserialize (reader);

How to get the answer in an XmL document :

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

My album class and root level class (thanks to help from Marc..I get it now):

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

My Serializer class:

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

True xml input which I am trying to Deserialize (yes, it has 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> 
+6
c # xml serialization xml-serialization
source share
9 answers

Personally, I won’t use constants here - they make it harder to detect errors (and since you are probably not reusing them, do not add a lot). For example:

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

It looks suspicious to me ...

A simpler approach is to write the xml you want to the file ( foo.xml , say), and use:

 xsd foo.xml xsd foo.xsd /classes 

Then look at foo.cs

+5
source share

Here we say that xml is not valid ( & should be &amp; use idle xsi namespace-alias). Also note that I added an enumeration for visibility, added processing to convert long to DateTime and added a shell type:

 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; } } 
+3
source share

(February 08) Firstly, processing xml as a string (for reading) will not cause errors.

The problem is the namespace ( xmlns without xsi ); it was not in early xml, so I could not include it ... basically, you need to tell the serializer about it:

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

In this case, the constant for the namespace will make sense (since you are reusing it).

If the xml you are showing is accurate, then the links are still broken, though ... but maybe it's just copy / paste (i.e. don't apply this change until you find out about the errors ...): you required &amp; (not & ). Suggest some Replace ... at the roughest level:

 string fixedXml = xml.Replace("&", "&amp;"); 

(although something more precise might be better - perhaps a regex)

Note that with different data, I also had to make some rows of data (rather than long):

 [XmlElement("aid")] public string AlbumID { get; set; } [XmlElement("cover_pid")] public string CoverPhotoID { get; set; } [XmlElement("owner")] public string Owner { get; set; } 

With these changes (and mainly with my source code) it works.

Of course, at this point you should be thinking, "I would like to use xsd ."

+2
source share

Well,

there is a link from Microsoft aimed at your problem

+1
source share

Yes - the album is definitely not the root of the node in your XML.

I would recommend that you create a GetAlbumsResponse class that contains a list of albums and move the deserialization code to a wrapper class.

Basically, remove the root element from the definition of your album class and:

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

}

+1
source share

Good - I coded an example. I took a look at the Facebook API, now here is a complete working example. Try the following:

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

Now .. with xml photos_getAlbums_response from the Facebook API,

You can deserialize as follows:

  GetAlbumsResponse response = XmlUtils.DeserializeFromXml<GetAlbumsResponse>(xmlResponseString); 
+1
source share

The xml that will work for your current code looks something like this:

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

The answer, in which there is an array of albums, where each album has an answer, which is an array of albums ... etc.

In any case, I already helped you with your other question and even set the task to create a sample of the full working code. Why did you create another question on the same issue?

+1
source share

Use System.Xml.XmlDocument to parse input. No more than an hour to write code to extract the data yourself.

+1
source share

This is a really old thread, but I just ran into the same problem as myself when I tried to serialize two different types of list in the same class under the same name XmlArray, something like

  <Root> <ArrayNode> <SubnodeType1>...</SubnodeType1> <SubnodeType1>...</SubnodeType1> </ArrayNode> </Root> Or <Root> <ArrayNode> <SubnodeType2>...</SubnodeType2> <SubnodeType2>...</SubnodeType2> </ArrayNode> </Root> 

What worked for me was to use class decoration, for example:

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

Hope this helps someone else :)

0
source share

All Articles