#c# #xml
Вопрос:
У меня есть xml из ответа soap, который выглядит следующим образом (формат которого я не контролирую), обратите внимание на вложенные 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>
У меня есть следующие занятия:
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; }
}
}
Я пытаюсь десериализовать данный xml с помощью этого кода
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);
}
И это значение responseCampaigns
в конце:
Проблема
responseCampaigns.CampaignCount
правильно проанализирован/установлен responseCampaigns.Campaign.CampaignId
и responseCampaigns.Campaign.Name
оба являются нулевыми, так как я неправильно учитываю Campaigns.Campaign.Campaign
вложенность
Как я могу изменить структуру модели, чтобы правильно учесть Campaigns.Campaign.Campaign
вложенность?
Комментарии:
1. Изменение модели-это единственный вариант, который у вас есть? Вы можете удалить один узел кампании. Чтобы кампании могли иметь узлы для кампании, в которой используется ваша модель кампании.
2. @DhavalR К сожалению, я не контролирую входящий XML-файл или формат. Я открыт для другого подхода, если мне нужно извлечь кампании. Кампания. Однако кампания ведется по-другому.
3. У вас может быть свойство в классе Campaign, которое возвращает объект самой кампании. Сделайте этот класс одноэлементным. Надеюсь, это сработает для вас.
Ответ №1:
У вас есть два разных пространства имен»…», что создает проблему. Попробуйте код ниже :
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:temptest.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; }
}
}
Комментарии:
1. Спасибо за вашу помощь jdweng, я пытался реализовать это таким образом, но столкнулся с некоторыми проблемами с неожиданными элементами в xml (конечно, это моя вина). Экспериментируя с тем, что я узнал из вашего подхода, я заставил его работать, изменив свою модель кампаний, чтобы указать XmlArrayItem и XmlArray как с кампанией имени элемента, так и с изменением участника кампании на список
Ответ №2:
Изменение модели моих кампаний для указания XmlArrayItem и XmlArray как в кампании с именем элемента, так и в изменении участника кампании на Список решило эту проблему для меня.
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; }
}
}