0

I'm trying to convert the XML data to an object list, but it throws an error.

XML

<?xml version="1.0" encoding="utf-8" ?>
<Servers>
  <Server>
    <ServerName>STAGING</ServerName>
    <ServerIP>XXX.XXX.XX.X</ServerIP>        
  </Server>
</Servers>

C#

public class ServerDetails
{
    public string ServerName { get; set; }
    public string ServerIP { get; set; }        
}

private void GetXMLData()
{
  XmlSerializer serializer = new XmlSerializer(typeof(List<ServerDetails>));

  using (FileStream stream = File.OpenRead("D:\\Resource.xml"))
  {
    List<ServerDetails> list = (List<ServerDetails>)serializer.Deserialize(stream);
    //Exception here
  }
}

ERROR

Inner Exception : <Servers xmlns=''> was not expected.   
There is an error in XML document (2,2)

I tried adding the [Serializabe] and [XMLElement] attributes to the class,
and also xmlns="http://www.example.com/xsd/ServerDetails" in the XML
but that did not help.

1
  • 1
    You can analyze the problems by first serialize an object first and view the resulting XML. Commented May 27, 2016 at 5:43

3 Answers 3

2

You have ServerDetails as your class name and in the xml the tag name is different, Try something like this.

public class ServerDetails
{
   public string ServerName { get; set; }
   public string ServerIP { get; set; }        
}

public class ServerList
{
   [XmlArray("Servers")]
   [XmlArrayItem("Server", Type = typeof(ServerDetails))]
   public ServerDetails[] Servers { get;set;}        
}

private void GetXMLData()
{
   XmlSerializer serializer = new XmlSerializer(typeof(ServerList));

   using (FileStream stream = File.OpenRead("D:\\Resource.xml"))
   {
      var list = (ServerList)serializer.Deserialize(stream);
      //Exception here
   }
}
Sign up to request clarification or add additional context in comments.

1 Comment

It's the same exception still.
2

I used to use XmlSerializer a lot, but I totally stopped using it because you are forced to create your object structure fitting the xml structure. That makes it hard to maintain. Also XmlSerializer has some serious memory leaks.

If you don't mind, I would suggest to switch to XElement

    public IEnumerable<ServerDetails> GetServers(string file)
    {
        using (var stream = File.Open(file, FileMode.Open, FileAccess.Read))
            return GetServers(stream);
    }

    public IEnumerable<ServerDetails> GetServers(Stream stream)
    {
        var root = XElement.Load(stream);
        return GetServers(root);
    }

    public IEnumerable<ServerDetails> GetServers(XElement root)
    {
        foreach (var server in root.Elements("Server"))
        {
            yield return new ServerDetails
            {
                ServerName = (string)server.Element("ServerName"),
                ServerIP = (string)server.Element("ServerIP"),
            };
        }
    }

Please note that you have to reference System.Xml.Linq

For your convenience here is a test case.

    [TestMethod]
    public void CanReadServers()
    {
        var xml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + @"
<Servers>
  <Server>
    <ServerName>STAGING</ServerName>
    <ServerIP>XXX.XXX.XX.X</ServerIP>
  </Server>
</Servers>";

        IEnumerable<ServerDetails> servers;
        using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
            servers = GetServers(stream).ToList();

        Assert.AreEqual(1, servers.Count());
        Assert.AreEqual("STAGING", servers.ElementAt(0).ServerName);
        Assert.AreEqual("XXX.XXX.XX.X", servers.ElementAt(0).ServerIP);
    }

Comments

1

Use XmlElement Notation to specify the element name.

public class Servers
{        
    [XmlElement("Server")]
    public ServerDetails[] ServersDetails { get; set; }
}

public class ServerDetails
{
    public string ServerName { get; set; }
    public string ServerIP { get; set; }
}


private void GetXMLData()
{
  XmlSerializer serializer = new XmlSerializer(typeof(Servers));

  using (FileStream stream = File.OpenRead("D:\\Resource.xml"))
  {
    Servers list = (Servers)serializer.Deserialize(stream);
    //Exception here
  }
}

1 Comment

Make sure the code is the same, It's working fine for me, see demo at: dotnetfiddle.net/7JCmcX

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.