使用多个名称空间反序列化肥皂响应

时间:2019-09-10 05:28:50

标签: c# xml soap xml-deserialization soapformatter

我在尝试反序列化下面的肥皂响应时遇到了很大的困难。 我认为是因为存在多个命名空间,或者可能是由于复杂的类型(序列化数组)

Soapformatter抛出一个Object引用异常,其他手动反序列化返回一个空对象。此时,我只能假定我没有正确标记对象。什么是正确的方法来构建下面的BatchResponse对象,以便它可以从此响应中反序列化?

    <?xml version="1.0" encoding="UTF-8"?>
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
   <s:Header>
      <a:Action s:mustUnderstand="1">https://example.com/operations/fetch/BatchResponse</a:Action>
   </s:Header>
   <s:Body>
      <BatchResponse xmlns="https://example.com/operations">
         <BatchResult xmlns:b="https://example.com/responses" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
            <b:FailureMessages xmlns:c="http://schemas.microsoft.com/2003/10/Serialization/Arrays" i:nil="true" />
            <b:FailureType i:nil="true" />
            <b:ProcessedSuccessfully>true</b:ProcessedSuccessfully>
            <b:SessionId>1961810</b:SessionId>
            <b:TotalPages>38</b:TotalPages>
         </BatchResult>
      </BatchResponse>
   </s:Body>
</s:Envelope>

还假设Soapformatter继续抛出异常-正确的方法是“ xpath”到BatchResponse对象,以便我提取并反序列化?

谢谢

2 个答案:

答案 0 :(得分:1)

尝试以下操作:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace ConsoleApplication131
{
    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(ElementName = "Envelope", Namespace = "http://www.w3.org/2003/05/soap-envelope")]
    public class Envelope
    {
        [XmlElement(ElementName = "Header", Namespace = "http://www.w3.org/2003/05/soap-envelope")]
        public Header header { get; set; }

        [XmlElement(ElementName = "Body", Namespace = "http://www.w3.org/2003/05/soap-envelope")]
        public Body body { get; set; }
    }
    [XmlRoot(ElementName = "Header", Namespace = "http://www.w3.org/2003/05/soap-envelope")]
    public class Header
    {
        [XmlElement(ElementName = "Action", Namespace = "http://www.w3.org/2005/08/addressing")]
        public Action action { get; set; }
    }
    [XmlRoot(ElementName = "Action", Namespace = "http://www.w3.org/2005/08/addressing")]
    public class Action
    {
        [XmlAttribute(AttributeName = "mustUnderstand", Namespace = "http://www.w3.org/2003/05/soap-envelope")]
        public int mustUnderstand { get; set;}
        [XmlText]
        public string value { get;set;}
    }
    [XmlRoot(ElementName = "Body", Namespace = "")]
    public class Body
    {
        [XmlElement(ElementName = "BatchResponse", Namespace = "https://example.com/operations")]
        public BatchResponse batchResponse { get; set; }
    }
    [XmlRoot(ElementName = "BatchResponse", Namespace = "https://example.com/operations")]
    public class BatchResponse
    {
        [XmlElement(ElementName = "BatchResult", Namespace = "https://example.com/operations")]
        public BatchResult batchResult { get; set; }
    }
    [XmlRoot(ElementName = "BatchResult", Namespace = "https://example.com/operations")]
    public class BatchResult
    {
        [XmlElement(ElementName = "FailureMessages", Namespace = "https://example.com/responses")]
        public string failureMessages { get; set; }

        [XmlElement(ElementName = "FailureType", Namespace = "https://example.com/responses")]
        public string failureType { get; set; }

        [XmlElement(ElementName = "ProcessedSuccessfully", Namespace = "https://example.com/responses")]
        public Boolean  processedSuccessfully { get; set; }

        [XmlElement(ElementName = "SessionId", Namespace = "https://example.com/responses")]
        public string sessionId { get; set; }

        [XmlElement(ElementName = "TotalPages", Namespace = "https://example.com/responses")]
        public int totalPages { get; set; }

    }
}

答案 1 :(得分:0)

您可以使用local-name()忽略xpath中的名称空间

//*[local-name()='Envelope']/*[local-name()='Body']/*[local-name()='BatchResponse']