из предоставленного 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
.
Код можно еще более упростить, но я хотел показать каждый шаг как можно более понятным.