0
votes
<?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>
        <GetMessage xmlns="http://tempuri.org/">
            <GetMessageResult>
                <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
                    <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
                        <xs:complexType>
                            <xs:choice minOccurs="0" maxOccurs="unbounded">
                                <xs:element name="inLogSMS">
                                    <xs:complexType>
                                        <xs:sequence>
                                            <xs:element name="InLogID" type="xs:int" minOccurs="0" />
                                            <xs:element name="FromMobile" type="xs:string" minOccurs="0" />
                                            <xs:element name="ContactName" type="xs:string" minOccurs="0" />
                                            <xs:element name="SMSText" type="xs:string" minOccurs="0" />
                                            <xs:element name="ReceiveAt" type="xs:dateTime" minOccurs="0" />
                                            <xs:element name="Status" type="xs:string" minOccurs="0" />
                                        </xs:sequence>
                                    </xs:complexType>
                                </xs:element>
                            </xs:choice>
                        </xs:complexType>
                    </xs:element>
                </xs:schema>
                <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
                    <NewDataSet xmlns="">
                        <inLogSMS diffgr:id="SMS1" msdata:rowOrder="0">
                            <InLogID></InLogID>
                            <FromMobile></FromMobile>
                            <ContactName></ContactName>
                            <SMSText>Test2</SMSText>
                            <ReceiveAt></ReceiveAt>
                            <Status>New</Status>
                        </inLogSMS>
                        <inLogSMS diffgr:id="SMS2" msdata:rowOrder="1">
                            <InLogID></InLogID>
                            <FromMobile></FromMobile>
                            <ContactName></ContactName>
                            <SMSText>TEST</SMSText>
                            <ReceiveAt></ReceiveAt>
                            <Status>New</Status>
                        </inLogSMS>
                    </NewDataSet>
                </diffgr:diffgram>
            </GetMessageResult>
        </GetMessage>

I been trying for days, anyone can tell me how to extract the data for SMSText element and Status Element. Thank you very much. There is too much tag till i am confuse

var responseXml = new XmlDocument();

XmlNodeList items = responseXml.GetElementsByTagName("/GetMessage/inLogSMS"); foreach (XmlNode xItem in items) { string id = xItem["SMSText"].InnerText; Console.WriteLine(id); Console.ReadLine(); }

2

2 Answers

1
votes

You don't even need the XPath-like expression to access the elements:

XmlDocument responseXml = new XmlDocument();
responseXml.Load("path to your XML");

foreach (XmlElement e in responseXml.GetElementsByTagName("inLogSMS"))
{
    Console.WriteLine("Text: " + e.GetElementsByTagName("SMSText")[0].InnerText);
    Console.WriteLine("Status: " + e.GetElementsByTagName("Status")[0].InnerText);
}


Instead of XmlDocument you could use XDocument.

At first, you need to load the XML; there are two ways of doing so:
1. XDocument x = XDocument.Parse("your XML as string");
2. XDocument x = XDocument.Load("The path to your XML");

After that, you can access any element by using Descendants().

For example:

foreach (var e in x.Descendants("inLogSMS"))
{
    Console.WriteLine("Text: " + e.Element("SMSText").Value);
    Console.WriteLine("Status: " + e.Element("Status").Value);
}

Both ways will print:

Text: Test2
Status: New
Text: TEST
Status: New

0
votes

You are dealing with a SOAP message. You don't reveal how you got that content but I expect you didn't get it from a WCF Client as that would have solved most of your problems.

Luckily the System.ServiceModel namespace has plenty of support classes to deal with SOAP messages.

That XML you show is a SOAP Envelope and Body with a wrapped return of a DataSet. While you can go fiddle with XmlDocument or XDocument you can obtain that data from within the standard classes offered.

Let's look at how the Message class can help us here.

It offers methods to read the body of SOAP serialized messages.

// using System.Runtime.Serialization
// using System.ServiceModel.Channels

GetMessage body; // GetMessage is our custon serialization class
using(var rdr = XmlReader.Create(@"your.xml"))  // or use StringReader / MemoryStream
{
  var msg = Message.CreateMessage(rdr, Int32.MaxValue, MessageVersion.Soap11);
  body = msg.GetBody<GetMessage>();
}
// Now we can simply iterate over the Table
foreach(DataRow smsrow in body.GetMessageResult.Tables["inlogSMS"].Rows)
{
  // and smsrow has the fields in its ItemArray (accessible by its indexer)
  Console.WriteLine("Text: {0} with status {1}", smsrow["SMSText"], smsrow["Status"]);
} 

The above code will output:

Text: Test2 with status New
Text: TEST with status New

The serialization class you need will look like this:

[DataContract(Name="GetMessage", Namespace="http://tempuri.org/")]
public class GetMessage
{
  [DataMember]
  public DataSet GetMessageResult {get;set;} // this will hold the DataSet
}