Reputation: 19571
I have xml from a soap response that looks like the below (which I dont control the format of), note the nested Campaigns.Campaign.Campaign
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
// ...
</s:Header>
<s:Body>
<SomeResponse xmlns="...">
<SomeCampaignsResult xmlns:b="..." xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<b:Campaigns>
<b:Campaign>
<b:Campaign>
<b:CampaignId>dfdf-dfe-fdf</b:CampaignId>
<b:CampaignName>Some name</b:CampaignName>
</b:Campaign>
</b:Campaign>
<b:CampaignCount>1</b:CampaignCount>
</b:Campaigns>
</SomeCampaignsResult>
</SomeResponse>
</s:Body>
</s:Envelope>
I have the following classes:
namespace Models
{
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "...")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "...", IsNullable = false)]
public class Campaigns
{
public int CampaignCount { get; set; }
public Campaign Campaign { get; set; }
}
}
namespace Models
{
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "...")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "...", IsNullable = false)]
public class Campaign
{
public string CampaignId { get; set; }
public string Name { get; set; }
}
}
Im trying to deserialize the given xml with this code
XmlDocument SOAPResponse = new XmlDocument();
SOAPResponse.Load("C:\\campaign.xml");
XmlNamespaceManager nsmgr = new XmlNamespaceManager(SOAPResponse.NameTable);
nsmgr.AddNamespace("s", "http://www.w3.org/2003/05/soap-envelope");
nsmgr.AddNamespace("a", "http://www.w3.org/2005/08/addressing");
nsmgr.AddNamespace("b", "...");
nsmgr.AddNamespace("i", "http://www.w3.org/2001/XMLSchema-instance");
XmlNode justNodes1 = SOAPResponse.SelectSingleNode("//s:Envelope/s:Body", nsmgr);
XmlNode nodeCampaigns = justNodes1.SelectSingleNode(".//b:Campaigns", nsmgr);
Campaigns responseCampaigns = null;
XmlSerializer serializerCampaigns = new XmlSerializer(typeof(Campaigns));
using (XmlReader reader = new XmlNodeReader(nodeCampaigns))
{
responseCampaigns = (Campaigns)serializerCampaigns.Deserialize(reader);
}
And this is the value of responseCampaigns
at the end:
responseCampaigns.CampaignCount
is correctly parsed/set
responseCampaigns.Campaign.CampaignId
and responseCampaigns.Campaign.Name
are both null since I am not properly accounting for the Campaigns.Campaign.Campaign
nesting
How can I change my model structure to properly account for the Campaigns.Campaign.Campaign
nesting?
Upvotes: 1
Views: 77
Reputation: 19571
Changing my Campaigns model to specify XmlArrayItem and XmlArray both with the ElementName Campaign and changing the Campaign member to a List solved this problem for me.
namespace Models
{
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "...")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "...", IsNullable = false)]
public class Campaigns
{
public int CampaignCount { get; set; }
[XmlArrayItem(ElementName = "Campaign")]
[XmlArray(ElementName = "Campaign")]
public List<Campaign> Campaign { get; set; }
}
}
Upvotes: 1
Reputation: 34421
You have two different namespace "..."which is giving an issue. Try code below :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
namespace ConsoleApplication183
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
XmlReader reader = XmlReader.Create(FILENAME);
XmlSerializer serializer = new XmlSerializer(typeof(Envelope));
Envelope envelope = (Envelope)serializer.Deserialize(reader);
}
}
[XmlRoot(Namespace = "http://www.w3.org/2003/05/soap-envelope")]
public class Envelope
{
[XmlElement(Namespace = "http://www.w3.org/2003/05/soap-envelope")]
public Body Body { get; set; }
}
public class Body
{
[XmlArray(ElementName = "SomeResponse", Namespace = "empty")]
[XmlArrayItem(ElementName = "SomeCampaignsResult", Namespace = "empty")]
public List<CampaignsResult> CampaignsResult { get; set; }
}
public class CampaignsResult
{
[XmlArray(ElementName = "Campaigns", Namespace = "bspace")]
[XmlArrayItem(ElementName = "Campaign", Namespace = "bspace")]
public List<Campaigns> Campaigns { get; set; }
}
public class Campaigns
{
[XmlElement(Namespace = "bspace")]
public Campaign Campaign { get; set; }
}
public class Campaign
{
public string CampaignId { get;set;}
public string CampaignName { get; set; }
}
}
Upvotes: 1