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