I'm trying to serialize the below XML into a class object, which I have listed below. I'm only interested in the planId
and name
attributes. I want this back as a list<Plan>
objects.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<apim:ApimQueryResult xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bns="http://api.platform.boomi.com/" xmlns:apim="http://apim.api.platform.boomi.com/" numberOfResults="3">
<bns:result xsi:type="apim:Plan" planId="1" name="Client 1" description="Unlimited api access" maxMessageSize="0" rateLimit="0" rateLimitUnit="HOUR" quotaLimit="0" quotaLimitUnit="DAY" status="ENABLED"/>
<bns:result xsi:type="apim:Plan" planId="2" name="Client 2" description="" maxMessageSize="0" rateLimit="0" rateLimitUnit="HOUR" quotaLimit="0" quotaLimitUnit="DAY" status="ENABLED"/>
<bns:result xsi:type="apim:Plan" planId="3" name="Client 3" description="" maxMessageSize="0" rateLimit="0" rateLimitUnit="HOUR" quotaLimit="0" quotaLimitUnit="DAY" status="ENABLED"/>
</apim:ApimQueryResult>
Class Plan
public class Plan
{
public int planId { get; set; }
public string planName { get; set; }
}
XmlDocument doc = new XmlDocument();
doc.LoadXml(response.Result);
if (doc != null)
{
var nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("bns", "http://api.platform.boomi.com/");
var nodes = doc.SelectNodes(@"//bns:result", nsmgr);
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Plan));
foreach(XmlNode node in nodes)
{
XmlNodeReader xmlReader = new XmlNodeReader(node);
Plan plan = (Plan)xmlSerializer.Deserialize(xmlReader);
plans.Add(plan);
}
}
I receive an error:
InvalidOperationException: <result xmlns='http://api.platform.boomi.com/'> was not expected.
You are getting the error because the Plan
class has planName
but the attribute in the xml is actually name
. Try adding xml attribute like this:
public class Plan {
public int planId { get; set; }
[XmlAttribute("name")]
public string planName { get; set; }
}
Edit to get around new exception:
I added 2 attributes to Plan
. First the XmlTypeAttribute
is specifying the other namespace in the response.
I'm honestly not sure how XmlRootAttribute
is helping here but this is the only way I can get it to run 😅. To me, "result" looks like an child element not a root but here we are...
[XmlType(Namespace = "http://apim.api.platform.boomi.com/")]
[XmlRoot(ElementName = "result", Namespace = "http://api.platform.boomi.com/")]
public class Plan
{
[XmlAttribute("planId")]
public int PlanId { get; set; }
[XmlAttribute("name")]
public string PlanName { get; set; }
}
Here is how I reproduced it:
using System.Xml;
using System.Xml.Serialization;
public class Program
{
[XmlType(Namespace = "http://apim.api.platform.boomi.com/")]
[XmlRoot(ElementName = "result", Namespace = "http://api.platform.boomi.com/")]
public class Plan
{
[XmlAttribute("planId")]
public int PlanId { get; set; }
[XmlAttribute("name")]
public string PlanName { get; set; }
}
static void Main(string[] args)
{
var response = @"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?>
<apim:ApimQueryResult xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:bns=""http://api.platform.boomi.com/"" xmlns:apim=""http://apim.api.platform.boomi.com/"" numberOfResults=""3"">
<bns:result xsi:type=""apim:Plan"" planId=""1"" name=""Client 1"" description=""Unlimited api access"" maxMessageSize=""0"" rateLimit=""0"" rateLimitUnit=""HOUR"" quotaLimit=""0"" quotaLimitUnit=""DAY"" status=""ENABLED""/>
<bns:result xsi:type=""apim:Plan"" planId=""2"" name=""Client 2"" description="""" maxMessageSize=""0"" rateLimit=""0"" rateLimitUnit=""HOUR"" quotaLimit=""0"" quotaLimitUnit=""DAY"" status=""ENABLED""/>
<bns:result xsi:type=""apim:Plan"" planId=""3"" name=""Client 3"" description="""" maxMessageSize=""0"" rateLimit=""0"" rateLimitUnit=""HOUR"" quotaLimit=""0"" quotaLimitUnit=""DAY"" status=""ENABLED""/>
</apim:ApimQueryResult>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(response);
var plans = new List<Plan>();
if (doc != null)
{
var nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("bns", "http://api.platform.boomi.com/");
var nodes = doc.SelectNodes(@"//bns:result", nsmgr);
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Plan));
foreach (XmlNode node in nodes)
{
XmlNodeReader xmlReader = new XmlNodeReader(node);
Plan plan = (Plan)xmlSerializer.Deserialize(xmlReader);
plans.Add(plan);
}
}
foreach (Plan plan in plans)
{
Console.WriteLine(plan.PlanId);
Console.WriteLine(plan.PlanName);
}
}
}