How to deserialize a difficult XML format in C# object and read it in order to use its values?

Viewed 825

I have a very difficult formatted XML document , which I want to read it and use its parameters.

This is the XML that I want to deserialize:

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
  xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Body>
      <APIResponse xmlns="https://testwebservice.com/">
          <Result>Api Result Message</Result>
      </APIResponse>
    </soap:Body>
</soap:Envelope>

I have tried some code samples that I found in some other question here

APIResponse envelopeClass = new APIResponse();
XmlSerializer serializer = new XmlSerializer(typeof(APIResponse), new XmlRootAttribute("Envelope"));
StringReader stringReader = new StringReader(xmlString);
envelopeClass = (APIResponse)serializer.Deserialize(stringReader);

But nothing has helped me so far , as I get an ERROR like this:

System.InvalidOperationException: 'There is an error in XML document (1, 42).'
Inner Exception
InvalidOperationException: <Envelope xmlns='http://schemas.xmlsoap.org/soap/envelope/'> was not expected.

These are the classes that I have used so far with the Paste Special button in Visual Studio.

[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://schemas.xmlsoap.org/soap/envelope/")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://schemas.xmlsoap.org/soap/envelope/", IsNullable = false)]
public partial class Envelope
{
   public EnvelopeBody bodyField { get; set; }
}

[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://schemas.xmlsoap.org/soap/envelope/")]
public partial class EnvelopeBody
{
   [System.Xml.Serialization.XmlElementAttribute(Namespace = "https://testwebservice.com/")]
   public  APIResponse aPIResponseField { get; set; }
}

[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="https://testwebservice.com/")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="https://testwebservice.com/", IsNullable=false)]
public partial class APIResponse 
{
   public string resultField { get; set; }
}

Despite all these I have not understand why I get the above ERROR , I want to note that I have not fully understand how all this work. Anyway , if there is anyone that can help with this I would appreciate it.

Please show me which are the right classes that I should use with this XML format document and how to deserialize it.

1 Answers

The "Difficult XML Format" as you name it is actually a standard SOAP (Simple Object Access Protocol) message. SOAP is used as the communication protocol for XML based web services, which at first brings to mind that you may add a service reference for the web service from where you get this XML content. If you are getting this XML content from a web resource, please try to add it as a service reference.

If not and if you've just ended up with this XML content somehow, although there are examples of how to get the response object from inside the xml by parsing it and serializing only part of it, here is what I assume to be a more elaborate and safe way of achieving it.

Add NuGet Reference: Microsoft.Web.Services3

Change the class ApiResponse as follows (change the name resultField to Result)

[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "https://testwebservice.com/")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "https://testwebservice.com/", IsNullable = false)]
public partial class APIResponse
{
    public string Result { get; set; }
}

And then get the ApiResponse object using the SoapEnvelope class and its methods like:

using Microsoft.Web.Services3;

. . .
. . .

SoapEnvelope envelope = new SoapEnvelope();
envelope.LoadXml(xmlString);
APIResponse apiResponse = (APIResponse)envelope.GetBodyObject(typeof(APIResponse));

. . .
. . .
Related