繁体   English   中英

反序列化嵌套在自身中的 XML 节点

[英]Deserialize XML node nested in itself

我有来自 soap 响应的 xml ,如下所示(我不控制格式),注意嵌套的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.CampaignIdresponseCampaigns.Campaign.Name都是 null 因为我没有正确考虑Campaigns.Campaign.Campaign嵌套

如何更改我的 model 结构以正确考虑Campaigns.Campaign.Campaign嵌套?

您有两个不同的名称空间“...”,这是一个问题。 试试下面的代码:

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; }
    }

 
}

更改我的 Campaigns model以使用 ElementName Campaign 指定 XmlArrayItem 和 XmlArray 并将 Campaign 成员更改为 List 为我解决了这个问题。

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; }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM