How to extract the data from Soap Response in C#

a 夏天 提交于 2019-12-11 16:06:22

问题


Following is a part of the function which i use to extract data from.

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header/>
   <soapenv:Body>
      <MP0118_GetGridHeaderData_001_Result xmlns="http://schemas.datastream.net/MP_functions/MP0118_GetGridHeaderData_001_Result">
         <GRIDRESULT type="LIST.HEAD_DATA.STORED">

               <DATA jsonclass="array">
                  <ROW id="1">
                     <D n="6721">10128</D>
                     <D n="6724">CL</D>
                     <D n="6771">*</D>
                     <D n="6773">ACT</D>
                     <D n="6774">PHON</D>
                     <D n="6775">04-MAR-2018 21:54</D>
                     <D n="6779">MEP-IU</D>
                     <D n="6780">MEP-IU-010</D>
                     <D n="6782">CWP2B19-113</D>
                     <D n="6792">11410</D>
                     <D n="6809"/>
                     <D n="6880"/>
                     <D n="11651">Tap is not working in the Back of the Apt </D>
                     <D n="100410">40977</D>
                     <D n="101312">AHMED.ALI@MERAAS.AE</D>
                     <D n="101313">HANDOVER</D>
                  </ROW>
                  <ROW id="2">
                     <D n="6721">10132</D>
                     <D n="6724">CL</D>
                     <D n="6771">*</D>
                     <D n="6773">ACT</D>
                     <D n="6774">PHON</D>
                     <D n="6775">05-MAR-2018 11:27</D>
                     <D n="6779">GENERAL</D>
                     <D n="6780">GENERAL-005</D>
                     <D n="6782">CWP2B17-303</D>
                     <D n="6792"/>
                     <D n="6809"/>
                     <D n="6880"/>
                     <D n="11651">Flat 303, 304, 305 and 307 asking for Water Activation. Reporter is property manager. Please do the needful.</D>
                     <D n="100410">40981</D>
                     <D n="101312">AHMED.ELSHAHD@MERAAS.AE</D>
                     <D n="101313">CAM</D>
                  </ROW>
                  <ROW id="3">
                     <D n="6721">10177</D>
                     <D n="6724">CL</D>
                     <D n="6771">*</D>
                     <D n="6773">ACT</D>
                     <D n="6774">PHON</D>
                     <D n="6775">06-MAR-2018 14:41</D>
                     <D n="6779">MEP-IU</D>
                     <D n="6780">MEP-IU-006</D>
                     <D n="6782">CWP2B19-605</D>
                     <D n="6792">10600</D>
                     <D n="6809"/>
                     <D n="6880"/>
                     <D n="11651">City Walk Building 19, APT 605, The drainage inside whole apartment is smelling bad</D>
                     <D n="100410">41026</D>
                     <D n="101312">MOHAMED.SAEED@MERAAS.AE</D>
                     <D n="101313">HANDOVER</D>
                  </ROW>

               </DATA>
               <FIELDS viewtype="LIST" visibleColumn="true" visiblerowcount="">
                  <FIELD aliasnum="6721" control="text" filterable="+" keyfield="+" label="ctr_code" lookup="" name="ctr_code" order="1" type="VARCHAR" visible="+" width="180"/>
                  <FIELD aliasnum="6792" control="text" filterable="+" keyfield="-" label="ctr_contactinfoid" lookup="" name="ctr_contactinfoid" order="2" type="VARCHAR" visible="+" width="180"/>
                  <FIELD aliasnum="6809" control="text" filterable="+" keyfield="-" label="ctr_contactnote" lookup="" name="ctr_contactnote" order="3" type="MIXVARCHAR" visible="+" width="180"/>
                  <FIELD aliasnum="6774" control="text" filterable="+" keyfield="-" label="ctr_contactsource" lookup="" name="ctr_contactsource" order="4" type="VARCHAR" visible="+" width="180"/>
                  <FIELD aliasnum="6775" control="text" filterable="+" keyfield="-" label="ctr_created" lookup="" name="ctr_created" order="5" type="DATETIME" visible="+" width="180"/>
                  <FIELD aliasnum="101312" control="text" filterable="+" keyfield="-" label="ctr_createdby" lookup="" name="ctr_createdby" order="6" type="VARCHAR" visible="+" width="180"/>
                  <FIELD aliasnum="6880" control="text" filterable="+" keyfield="-" label="ctr_desc" lookup="" name="ctr_desc" order="7" type="MIXVARCHAR" visible="+" width="180"/>
                  <FIELD aliasnum="100410" control="text" filterable="+" keyfield="-" label="ctr_event" lookup="" name="ctr_event" order="8" type="VARCHAR" visible="+" width="180"/>
                  <FIELD aliasnum="101313" control="text" filterable="+" keyfield="-" label="ctr_mrc" lookup="" name="ctr_mrc" order="9" type="VARCHAR" visible="+" width="180"/>
                  <FIELD aliasnum="11651" control="text" filterable="+" keyfield="-" label="ctr_note" lookup="" name="ctr_note" order="10" type="MIXVARCHAR" visible="+" width="180"/>
                  <FIELD aliasnum="6782" control="text" filterable="+" keyfield="-" label="ctr_object" lookup="" name="ctr_object" order="11" type="VARCHAR" visible="+" width="180"/>
                  <FIELD aliasnum="6771" control="text" filterable="+" keyfield="-" label="ctr_org" lookup="" name="ctr_org" order="12" type="VARCHAR" visible="+" width="180"/>
                  <FIELD aliasnum="6779" control="text" filterable="+" keyfield="-" label="ctr_servicecategory" lookup="" name="ctr_servicecategory" order="13" type="VARCHAR" visible="+" width="180"/>
                  <FIELD aliasnum="6780" control="text" filterable="+" keyfield="-" label="ctr_serviceproblem" lookup="" name="ctr_serviceproblem" order="14" type="VARCHAR" visible="+" width="180"/>
                  <FIELD aliasnum="6724" control="text" filterable="+" keyfield="-" label="ctr_status" lookup="" name="ctr_status" order="15" type="VARCHAR" visible="+" width="180"/>
                  <FIELD aliasnum="6773" control="text" filterable="+" keyfield="-" label="ctr_type" lookup="" name="ctr_type" order="16" type="VARCHAR" visible="+" width="180"/>
               </FIELDS>
            </GRID>
         </GRIDRESULT>
      </MP0118_GetGridHeaderData_001_Result>
   </soapenv:Body>
</soapenv:Envelope>

this the code i m using for to filter the data,

#region Namespaces
using System;
using System.Data;
using System.IO;
using System.Net;
using System.Text;
using System.Windows.Forms;
using System.Xml;

using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;

#endregion

/// <summary>
/// This is the class to which to add your code.  Do not change the name, attributes, or parent
/// of this class.
/// </summary>
[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{

    public override void PreExecute()
    {
        base.PreExecute();


    }


    public override void PostExecute()
    {
        base.PostExecute();

    }

    public override void CreateNewOutputRows()
    {


        IvokeAPICalls(Variables.CRMAPIEndPoint1, Variables.CRMSoapRequest1);




    }



    private static void IvokeAPICalls(string APIEndPoint, string XmlRequest)
    {
        ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;

        HttpWebRequest httpWebRequest = (HttpWebRequest)(WebRequest.Create(APIEndPoint));
        httpWebRequest.Headers.Add(@"SOAP:Action");
        httpWebRequest.ContentType = "text/xml;charset=\"utf-8\"";
        httpWebRequest.Accept = "text/xml";
        httpWebRequest.Method = "POST";
        httpWebRequest.Timeout = 99999999;
        var fileContent = File.ReadAllText(XmlRequest);
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.Append(fileContent);//.Replace("@StartDate", StartDate).Replace("@EndDate", EndDate).Replace("@Operations", Operations);
        XmlDocument xmlDocument = new XmlDocument();
        xmlDocument.LoadXml(stringBuilder.ToString());

        using (Stream stream = httpWebRequest.GetRequestStream())
        {
            xmlDocument.Save(stream);
        }

        using (WebResponse response = httpWebRequest.GetResponse())
        {
            using (StreamReader streamreader = new StreamReader(response.GetResponseStream()))
            {
                string result1 = streamreader.ReadToEnd();
                 MessageBox.Show(result1);

                //Method1
                //xmlDocument = new XmlDocument();
                xmlDocument.LoadXml(result1);

                //foreach (XmlElement xmlElement in xmlDocument.DocumentElement.SelectNodes("//DATA/ROW[*]"))
                foreach (XmlElement xmlElement in xmlDocument.DocumentElement.SelectNodes("//GRIDRESULT/GRID/DATA/ROW[*]"))
                {
                    Console.WriteLine(xmlElement.OuterXml);

                    //MessageBox.Show(xmlElement.OuterXml);
                    string result2 = streamreader.ReadToEnd();
                }



                //Method2

                XmlDocument xmlDoc1 = new XmlDocument();
                xmlDoc.LoadXml(result1);

                XmlNamespaceManager xmlnsManager = new System.Xml.XmlNamespaceManager(xmlDoc1.NameTable);

                xmlnsManager.AddNamespace("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");
                xmlnsManager.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
                xmlnsManager.AddNamespace("xsd", "http://www.w3.org/2001/XMLSchema");
                xmlnsManager.AddNamespace("si", "http://schemas.datastream.net/MP_functions/MP0118_GetGridHeaderData_001_Result");

                XmlNode node = xmlDoc.SelectSingleNode("//si:DATA/ROW[*]", xmlnsManager);
                string name = node.InnerText; 
            }
        }
    }

}

this is what I tried to filter the data. but i m not getting.

I want to extract list of all records from response. I m not sure how to go about writing a code for to filter the data.

i want to fetch data from this soap respons exml i tried xml node xpath but didn't work.Please help to fetch data


回答1:


from the provided XML, it seems it's divided into two sections, rows and fields.

The fields are just a definitions for the rows. So, what you'll need to do is to make a class model with the fields using aliasnum and name and type of each field. for instance this :

<FIELD aliasnum="6721" control="text" filterable="+" keyfield="+" label="ctr_code" lookup="" name="ctr_code" order="1" type="VARCHAR" visible="+" width="180"/>

would be converted to this :

public class SoapField
{
    public string Aliasnum { get; set; }
    public string Name { get; set; }
}

here we took only the Aliasnum and the Name, which will be storing aliasnum and name. these two are what we need to map the rows.

now, taking the list of name attributes, we will create another class model for the rows based on it.

public class SoapRow
{
    public string Id { get; set; }         
    public string Code { get; set; }
    public string ContactInfoId { get; set; }
    public string ContactNote { get; set; }
    public string ContactSource { get; set; }
}    

now you'll need two loops, one to read these fields, the other one will be for the rows.

I have reduced the XML to four fields, just for demonstration purpose, you'll need to complete the rest as required. Example :

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header/>
   <soapenv:Body>
      <MP0118_GetGridHeaderData_001_Result xmlns="http://schemas.datastream.net/MP_functions/MP0118_GetGridHeaderData_001_Result">
         <GRIDRESULT type="LIST.HEAD_DATA.STORED">
            <GRID>
               <DATA jsonclass="array">
                  <ROW id="1">
                    <D n="6721">10128</D> <!-- code -->
                    <D n="6792">11410</D> <!-- contactinfoid -->
                    <D n="6809"/>         <!-- contactnote -->
                    <D n="6774">PHON</D>  <!-- contactsource -->
                  </ROW>
               </DATA>
               <FIELDS viewtype="LIST" visibleColumn="true" visiblerowcount="">
                  <FIELD aliasnum="6721" control="text" filterable="+" keyfield="+" label="ctr_code" lookup="" name="ctr_code" order="1" type="VARCHAR" visible="+" width="180"/>
                  <FIELD aliasnum="6792" control="text" filterable="+" keyfield="-" label="ctr_contactinfoid" lookup="" name="ctr_contactinfoid" order="2" type="VARCHAR" visible="+" width="180"/>
                  <FIELD aliasnum="6809" control="text" filterable="+" keyfield="-" label="ctr_contactnote" lookup="" name="ctr_contactnote" order="3" type="MIXVARCHAR" visible="+" width="180"/>
                  <FIELD aliasnum="6774" control="text" filterable="+" keyfield="-" label="ctr_contactsource" lookup="" name="ctr_contactsource" order="4" type="VARCHAR" visible="+" width="180"/>
               </FIELDS>
            </GRID>
         </GRIDRESULT>
      </MP0118_GetGridHeaderData_001_Result>
   </soapenv:Body>
</soapenv:Envelope>

then using the above classes we can do this :

var rowsList = new List<SoapRow>();
var fieldsList = new List<SoapField>(); 

//use XDocument instead of xmlDocument it's simpler and works very well with LINQ.
var doc = XDocument.Parse(xml);

// declare the namespace 
var ns = doc.Root.GetNamespaceOfPrefix("soapenv");

// get Body 
var body = doc.Descendants(ns + "Body").Elements();

// get MP0118_GetGridHeaderData_001_Result
var gridresultheader = body.ElementAt(0).Elements();

// get GRIDRESULT
var gridresult = gridresultheader.ElementAt(0).Elements();

// get GRID
var grid = gridresult.ElementAt(0).Elements();

// get DATA
var rows = grid.ElementAt(0).Elements();

// get FIELDS
var fields = grid.ElementAt(1).Elements();

// define the fields first
foreach(var field in fields)
{
    fieldsList.Add(
        new SoapField()
        {
            Aliasnum = field.Attribute("aliasnum").Value.Trim(), 
            Name = field.Attribute("name").Value.Substring(4).Trim() //get the name without (ctr_)
        }
        );
}

// now loop over the rows, and map them to the fields.
foreach (var row in rows)
{
    // get the row id
    var id = row.Attribute("id").Value.Trim();

    //get the row elements
    var d = row.Elements();

    //set the row id first
    var dataRow = new SoapRow
    {
        Id = id
    };

    // go over each element in the row
    foreach (var element in d)
    {
        // get the row n attribute
        var n = element.Attribute("n").Value.Trim();

        // get the name of this element by the n attribute from the fields definition.
        var name = fieldsList.Where(e => e.Aliasnum == n).Select(x => x.Name).First();

        // now just map it using a simple switch statment.
        switch(name)
        {
            case "code":
                dataRow.Code = element.Value.Trim();
                break;
            case "contactinfoid":
                dataRow.ContactInfoId = element.Value.Trim();
                break;
            case "contactnote":
                dataRow.ContactNote = element.Value.Trim();
                break;
            case "contactsource":
                dataRow.ContactSource = element.Value.Trim();
                break;
        }

    }

    // add the row results into the list 
    rowsList.Add(dataRow);

}

the results will be in the rowsList.

The code can be further simplified, but I wanted to show each step as clear as possible.




回答2:


There is a website https://xmltocsharp.azurewebsites.net/ which makes extract to c# maybe it will helps you



来源:https://stackoverflow.com/questions/58335910/how-to-extract-the-data-from-soap-response-in-c-sharp

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!