Reputation: 577
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Head>
<h:talkId s:mustknow="1" xmlns:h="urn:schemas-test:testgate:hotel:2012-06">
sfasfasfasfsfsf</h:talkId>
</s:Head>
<s:Body>
<bookHotelResponse xmlns="urn:schemas-test:testgate:hotel:2012-06" xmlns:d="http://someURL" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<d:bookingReference>123456</d:bookingReference>
<d:bookingStatus>successful</d:bookingStatus>
<d:price xmlns:p="moreURL">
<d:total>105</d:total>
</d:price>
</bookHotelResponse>
</s:Body>
</s:Envelope>
I am trying to read the above soap message XmlDocument
using C#:
XmlDocument document = new XmlDocument();
document.LoadXml(soapmessage); //loading soap message as string
XmlNamespaceManager manager = new XmlNamespaceManager(document.NameTable);
manager.AddNamespace("d", "http://someURL");
XmlNodeList xnList = document.SelectNodes("//bookHotelResponse", manager);
int nodes = xnList.Count;
foreach (XmlNode xn in xnList)
{
Status = xn["d:bookingStatus"].InnerText;
}
The count is always zero and it is not reading the bookingstatus values.
Upvotes: 14
Views: 64601
Reputation: 139
As I understand you want to get response from soap service. If so, you don't have to do all this hard work (making call, parsing xml, selecting nodes to get the response value) by yourself... instead you need to Add Service Reference to your project and it will do all the rest work for you, including generating class, making asmx call and so on... Read more about it here https://msdn.microsoft.com/en-us/library/bb628649.aspx
Everything you'll need to do after adding reference is to invoke a class method something like this
var latestRates = (new GateSoapClient())?.ExchangeRatesLatest();
return latestRates?.Rates;
Upvotes: 1
Reputation: 1875
First you want to create a class to deseralize the xml values into
public class bookHotelResponse {
public int bookingReference { get; set; }
public int bookingStatus { get; set; }
}
Then you can utilize GetElementsByTagName
to extract the body of the soap request and deseralize the request string into an object.
private static T DeserializeInnerSoapObject<T>(string soapResponse)
{
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(soapResponse);
var soapBody = xmlDocument.GetElementsByTagName("soap:Body")[0];
string innerObject = soapBody.InnerXml;
XmlSerializer deserializer = new XmlSerializer(typeof(T));
using (StringReader reader = new StringReader(innerObject))
{
return (T)deserializer.Deserialize(reader);
}
}
Upvotes: 2
Reputation: 15549
BookHotelResponse
is in the namespace urn:schemas-test:testgate:hotel:2012-06
(the default namespace in the sample xml) so you need to provide that namespace in your queries:
XmlDocument document = new XmlDocument();
document.LoadXml(soapmessage); //loading soap message as string
XmlNamespaceManager manager = new XmlNamespaceManager(document.NameTable);
manager.AddNamespace("d", "http://someURL");
manager.AddNamespace("bhr", "urn:schemas-test:testgate:hotel:2012-06");
XmlNodeList xnList = document.SelectNodes("//bhr:bookHotelResponse", manager);
int nodes = xnList.Count;
foreach (XmlNode xn in xnList)
{
Status = xn["d:bookingStatus"].InnerText;
}
Upvotes: 17
Reputation: 32787
Use LINQ2XML
To read bookingStatus,do this
XElement doc = XElement.Load("yourStream.xml");
XNamespace s = "http://schemas.xmlsoap.org/soap/envelope/";//Envelop namespace s
XNamespace bhr="urn:schemas-test:testgate:hotel:2012-06";//bookHotelResponse namespace
XNamespace d="http://someURL";//d namespace
foreach (var itm in doc.Descendants(s + "Body").Descendants(bhr+"bookHotelResponse"))
{
itm.Element(d+"bookingStatus").Value;//your bookingStatus value
}
LINQ2XML is cool though....:)
Upvotes: 3