Как извлечь данные из Soap Response в C # - PullRequest
0 голосов
/ 11 октября 2019

Ниже приведена часть функции, из которой я извлекаю данные.

<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>

это код, который я использую для фильтрации данных,

#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; 
            }
        }
    }

}

это то, чтоЯ пытался отфильтровать данные. но я не получаю.

Я хочу извлечь список всех записей из ответа. Я не уверен, как написать код для фильтрации данных.

Я хочу получить данные из этого мыльного отклика exml Я попробовал xml узел xpath, но не сработал. Пожалуйста, помогите получить данные

Ответы [ 2 ]

1 голос
/ 11 октября 2019

из предоставленного XML, кажется, он разделен на две секции, строки и поля.

Поля - это просто определения для строк. Итак, вам нужно создать модель класса с полями, используя aliasnum и name и type каждого поля. например, это:

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

будет преобразовано в это:

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

здесь мы взяли только Aliasnum и Имя, которое будет хранить aliasnum и name. эти два - то, что нам нужно для сопоставления строк.

Теперь, взяв список атрибутов name, мы создадим еще одну модель класса для строк на ее основе.

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; }
}    

теперь вам понадобятся два цикла, один для чтения этих полей, другой для строк.

Я сократил XML до четырех полей, просто для демонстрации вам нужно будет заполнить все остальное по мере необходимости. Пример:

<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>

, затем с помощью вышеупомянутых классов мы можем сделать это:

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);

}

результаты будут в rowsList.

Код можно еще более упростить, но я хотел показать каждый шаг как можно более понятным.

0 голосов
/ 11 октября 2019

Есть веб-сайт https://xmltocsharp.azurewebsites.net/, который делает извлечение для c #, может быть, это поможет вам

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...