The correct approach in VS is to create a service reference using the Add Service Reference in the project. This will auto-generate the necessary SOAP client code to read the XML. This is dramatically simpler than trying to manually parse a SOAP message which can be really complex, depending upon the service.
But if I needed a super simple solution for a demo or something I would either use simple string parsing or perhaps XDocument and XPath. The challenge is with XML namespaces, they are annoying to work with. Here's working code.
using (var reader = XmlReader.Create("test.xml"))
{
var root = XElement.Load(reader);
var ns = new XmlNamespaceManager(reader.NameTable);
ns.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
var results = root.XPathSelectElement("//soap:OTA_NotifRQ", ns);
if (results != null)
{
//Grab the namespace from the element
var resultsNs = results.GetDefaultNamespace();
if (results.Element(XName.Get("success", resultsNs.NamespaceName)) != null)
{
var token = results.Attribute("echotoken")?.Value;
};
};
};
Here's what it does.
- Load the XML and get the namespaces defined in it.
- Create a new dummy namespace that lines up with the namespace that SOAP uses.
- Use XPath to find the desired element using the dummy namespace name.
- If found then get the default namespace of this element.
- Find the first element in the results called 'success' taking the default namespace name of the element into account.
- If all that was successful then grab the desired attribute(s).
It is important to understand that for XDocument and XPath the XML names are fully qualified as namespace names, the actual prefix doesn't matter. It is simply an aliasing. So what the XML file uses to represent the SOAP namespace doesn't matter, but is still needed in order to map the SOAP element to a fully qualified namespace name. When you query XPath you simply have to ensure you are using the same fully qualified namespace name (hence the dummy namespace that was added).