Search code examples
c#soapxml-namespacesxmldocumentxml-deserialization

Deserialize XML to object with xmlns namespace problem


I keep getting the error message:

<ArrayOfThemes xmlns='http://brickset.com/api/'> was not expected.

Tried some things I found on the internet but they all fail.

This is the XML out put when I call the SOAP API:

<ArrayOfThemes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="https://brickset.com/api/">
  <themes>
    <theme>4 Juniors</theme>
    <setCount>24</setCount>
    <subthemeCount>5</subthemeCount>
    <yearFrom>2003</yearFrom>
    <yearTo>2004</yearTo>
  </themes>
</ArrayOfThemes>

Classes:

public class Themes
{
    [XmlElement("theme")]
    public string Theme { get; set; }
    [XmlElement("setCount")]
    public string SetCount { get; set; }
    [XmlElement("subthemeCount")]

    public string SubthemeCount { get; set; }
    [XmlElement("yearFrom")]

    public string YearFrom { get; set; }
    [XmlElement("yearTo")]

    public string YearTo { get; set; }
}

[Serializable, XmlRoot("ArrayOfThemes")]
public class ArrayOfThemes
{
    [XmlElement("themes")]
    public Themes Themes { get; set; }
}

And then normally the usual deserialize code. Still not able to convert the XML objects into a list of Themes.

How do you handle xmlns namespaces?


Solution

  • You can use an XmlTextReader to ignore the namespaces before you deserialize your result. Also, your ArrayOfThemes class should probably have an array of themes unless you only ever expect one. Below example works for deserializing that xml.

    class Program
    {
        static void Main(string[] args)
        {
            var xml = @"<ArrayOfThemes xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns=""https://brickset.com/api/"">
                <themes>
                <theme>4 Juniors</theme>
                <setCount>24</setCount>
                <subthemeCount>5</subthemeCount>
                <yearFrom>2003</yearFrom>
                <yearTo>2004</yearTo>
                </themes>
                </ArrayOfThemes>";
            var ms = new MemoryStream(Encoding.UTF8.GetBytes(xml));
            var reader = new XmlTextReader(ms) {Namespaces = false};
            var serializer = new XmlSerializer(typeof(ArrayOfThemes));
    
            var result = (ArrayOfThemes) serializer.Deserialize(reader);
        }
    }
    
    public class Themes
    {
        [XmlElement("theme")]
        public string Theme { get; set; }
        [XmlElement("setCount")]
        public string SetCount { get; set; }
        [XmlElement("subthemeCount")]
    
        public string SubthemeCount { get; set; }
        [XmlElement("yearFrom")]
    
        public string YearFrom { get; set; }
        [XmlElement("yearTo")]
    
        public string YearTo { get; set; }
    }
    
    [Serializable, XmlRoot("ArrayOfThemes")]
    public class ArrayOfThemes
    {
        [XmlElement("themes")]
        public Themes[] Themes { get; set; }
    }