使用Linq从IEnumerable 中提取并存储在数据表中

我有一个如下所示的数据表

public static DataTable SetColumnHeaders(DataTable KeyDataTable) { KeyDataTable.Columns.Add("First_Name", typeof(string)); KeyDataTable.Columns.Add("Last_Name", typeof(string)); KeyDataTable.Columns.Add("Address1", typeof(string)); KeyDataTable.Columns.Add("Address2", typeof(bool)); KeyDataTable.Columns.Add("City", typeof(string)); KeyDataTable.Columns.Add("State", typeof(bool)); KeyDataTable.Columns.Add("Zip", typeof(string)); KeyDataTable.Columns.Add("Zip4", typeof(bool)); KeyDataTable.Columns.Add("Match_File", typeof(bool)); return KeyDataTable; } 

我的目标是从xml中读取信息并将该特定数据存储到我的数据表中。 我为每个“Quote”都有一个单独的xml文件,所以我将向数据表添加一个新行。 我关心的xml部分如下:

  '-  -  -  -  com.agencyport  -  NONE default   2006-04-04T15:44:00 en-US -  Applied Systems WinTam 7.1.0   -  81913CB5-3EAB-F158-EE24-5910F9BE9C26 -  7B010E52-44F2-487A-521B-9D1E3500C23D -  -  AP       TEST TEST TEST   SSN    MailingAddress 100 MAIN ST Howell MI 48843 Livingston    Phone Home 313-272-6576     Insured    Employer      

到目前为止我想出的是:

 public static void ExportAutoToText() { DirectoryInfo AutoDir = new DirectoryInfo(FilePrep.AutoDirectory); DataTable AutoDataTable = new DataTable(); AutoDataTable = SetColumnHeaders(AutoDataTable); // set column headers foreach (FileInfo File in AutoDir.GetFiles()) { DataRow fileRow = AutoDataTable.NewRow(); XDocument xmlDoc = XDocument.Load(AutoDir + File.Name); //decide if i want to keep the file IEnumerable personinfo = from per in xmlDoc.Root.Descendants("InsuredOrPrincipal") where (string)per.Element("InsuredOrPrincipalInfo") .Element("InsuredOrPrincipalRoleCd") == ("Insured") select per; // I then want to update the information in my datatable //fileRow["First_Name"] = xVal.Element("GeneralPartyInfo") // .Element("NameInfo") // .Element("PersonName") // .Element("GivenName"); //fileRow["Last_Name"] = xVal.Element("GeneralPartyInfo") // .Element("NameInfo") // .Element("PersonName") // .Element("Surname"); } } 

这个方法在一个类中,所以你可以假设获取文件,一切正常。 我只需要知道从xml文件访问数据并将其存储在我的数据表中的最有效方法。 我尝试循环数据如下:

 foreach (var Xval in personinfo) { //get the element info } 

我只是不太了解xml知道如何访问它。再次感谢,如果您需要更多信息,请告诉我。 **

我更喜欢为每个节点级别创建对象。 它更容易调试和测试。

使用这个xml库 。

您将为每个部分创建类,例如:

 public class InsuredOrPrincipal { XElement self; public InsuredOrPrincipal(XElement self) { this.self = self; } public GeneralPartyInfo GeneralPartyInfo { get { return _GeneralPartyInfo ?? (_GeneralPartyInfo = new GeneralPartyInfo(self.GetElement("GeneralPartyInfo"))); } } GeneralPartyInfo _GeneralPartyInfo; public InsuredOrPrincipalInfo InsuredOrPrincipalInfo { get { return _InsuredOrPrincipalInfo ?? (_InsuredOrPrincipalInfo = new InsuredOrPrincipalInfo(self.GetElement("InsuredOrPrincipalInfo"))); } } InsuredOrPrincipalInfo _InsuredOrPrincipalInfo; } public class GeneralPartyInfo { XElement self; public GeneralPartyInfo(XElement self) { this.self = self; } public NameInfo NameInfo { get { return _NameInfo ?? (_NameInfo = new NameInfo(self.GetElement("NameInfo"))); } } NameInfo _NameInfo; } public class InsuredOrPrincipalInfo { XElement self; public InsuredOrPrincipalInfo(XElement self) { this.self = self; } public string InsuredOrPrincipalRoleCd { get { return self.Get("InsuredOrPrincipalRoleCd", string.Empty); } } } public class NameInfo { XElement self; public NameInfo(XElement self) { this.self = self; } public PersonName PersonName { get { return _PersonName ?? (_PersonName = new PersonName(self.GetElement("PersonName"))); } } PersonName _PersonName; } public class PersonName { XElement self; public PersonName(XElement self) { this.self = self; } public string Surname { get { return self.Get("Surname", string.Empty); } set { self.Set("Surname", value, false); } } } 

你会像这样使用它:

 foreach (FileInfo File in AutoDir.GetFiles()) { DataRow fileRow = AutoDataTable.NewRow(); XDocument xmlDoc = XDocument.Load(AutoDir + File.Name); InsuredOrPrincipal[] insured = xmlDoc.Root .Descendants("InsuredOrPrincipal") .Select(x => new InsuredOrPrincipal(x)) .Where(ip => ip.InsuredOrPrincipalInfo.InsuredOrPrincipalRoleCd == "Insured") .ToArray(); foreach(var person in insured) { string surname = person.GeneralPartyInfo.NameInfo.PersonName.Surname; } } 

根据您的需要,您可以根据需要扩展或缩小每个类的类和信息的数量,但这是我的方式,因为它对我来说更有意义。

使用此代码进行测试:

 XElement test = new XElement("test"); var ip = new InsuredOrPrincipal(test); ip.GeneralPartyInfo.NameInfo.PersonName.Surname = "Surname"; test.Save(Path.Combine(Application.StartupPath, "insuredOrPrincipal.xml")); 

这给了我预期的输出:

      Surname     

您可以将“isInsured”检查和您选择的人员烘焙到一个查询中;

 var query = from p in xmlDoc.Elements() where ((string)p.Element("InsuredOrPrincipalInfo") .Element("InsuredOrPrincipalRoleCd")) == "Insured" select new { Firstname = (string)p.Element("GeneralPartyInfo") .Element("NameInfo") .Element("PersonName") .Element("GivenName"), LastName = (string)p.Element("GeneralPartyInfo") .Element("NameInfo") .Element("PersonName") .Element("Surname"), }; var person = query.FirstOrDefault(); if (person != null) { var fileRow = AutoDataTable.NewRow(); fileRow["First_Name"] = person.Firstname; fileRow["Last_name"] = person.LastName; } 

在处理意外格式的XML方面,这不是非常强大,但它应该是一个很好的起点。 只需使用其余元素填写匿名对象初始化,然后转换为所需类型。

这就是我到目前为止所拥有的。

 using System; using System.Collections.Generic; using System.Linq; using System.Xml.Linq; using System.IO; using System.Data; namespace xmlCustomReformat { class importXml { public DataTable _ComboDataTable; public void ExportAutoToText() { DirectoryInfo AutoDir = new DirectoryInfo(FilePrep.AutoDirectory); CreateDataTable(); // set column headers foreach (FileInfo File in AutoDir.GetFiles()) { DataRow fileRow = _ComboDataTable.NewRow(); XDocument xmlDoc = XDocument.Load(AutoDir + File.Name); InsuredOrPrincipal[] insured = xmlDoc.Root .Descendants("InsuredOrPrincipal") .Select(x => new InsuredOrPrincipal(x)) .Where(ip => ip.InsuredOrPrincipalInfo.InsuredOrPrincipalRoleCd == "Insured") .ToArray(); foreach (var person in insured) { fileRow["First_Name"] = person.GeneralPartyInfo.NameInfo.PersonName.GivenName; fileRow["Last_name"] = person.GeneralPartyInfo.NameInfo.PersonName.Surname; fileRow["Address1"] = person.GeneralPartyInfo.Addr.Address1; fileRow["City"] = person.GeneralPartyInfo.Addr.City; fileRow["State"] = person.GeneralPartyInfo.Addr.State; fileRow["Zip"] = person.GeneralPartyInfo.Addr.Zip; fileRow["Address2"] = " "; fileRow["Zip4"] = " "; fileRow["Match_File"] = File.Name.ToString(); _ComboDataTable.Rows.Add(fileRow); } } } public void ExportHomeToText() { DirectoryInfo HomeDir = new DirectoryInfo(FilePrep.HomeDirectory); foreach (FileInfo File in HomeDir.GetFiles()) { DataRow fileRow = _ComboDataTable.NewRow(); XDocument xmlDoc = XDocument.Load(HomeDir + File.Name); InsuredOrPrincipal[] insured = xmlDoc.Root .Descendants("InsuredOrPrincipal") .Select(x => new InsuredOrPrincipal(x)) .Where(ip => ip.InsuredOrPrincipalInfo.InsuredOrPrincipalRoleCd == "Insured") .ToArray(); foreach (var person in insured) { fileRow["First_Name"] = person.GeneralPartyInfo.NameInfo.PersonName.GivenName; fileRow["Last_name"] = person.GeneralPartyInfo.NameInfo.PersonName.Surname; fileRow["Address1"] = person.GeneralPartyInfo.Addr.Address1; fileRow["City"] = person.GeneralPartyInfo.Addr.City; fileRow["State"] = person.GeneralPartyInfo.Addr.State; fileRow["Zip"] = person.GeneralPartyInfo.Addr.Zip; fileRow["Address2"] = " "; fileRow["Zip4"] = " "; fileRow["Match_File"] = File.Name.ToString(); _ComboDataTable.Rows.Add(fileRow); } } ExportDataTable.Write(_ComboDataTable, HomeDir.Parent.FullName.ToString()); } public void CreateDataTable() { _ComboDataTable = new DataTable(); _ComboDataTable.Columns.Add("First_Name", typeof(string)); _ComboDataTable.Columns.Add("Last_Name", typeof(string)); _ComboDataTable.Columns.Add("Address1", typeof(string)); _ComboDataTable.Columns.Add("Address2", typeof(string)); _ComboDataTable.Columns.Add("City", typeof(string)); _ComboDataTable.Columns.Add("State", typeof(string)); _ComboDataTable.Columns.Add("Zip", typeof(string)); _ComboDataTable.Columns.Add("Zip4", typeof(string)); _ComboDataTable.Columns.Add("Match_File", typeof(string)); } } } 

Comp类看起来像这样。

 using System; using System.Collections.Generic; using System.Linq; using System.Xml.Linq; namespace xmlCustomReformat { public class InsuredOrPrincipal { XElement self; public InsuredOrPrincipal(XElement self) { this.self = self; } public GeneralPartyInfo GeneralPartyInfo { get { return _GeneralPartyInfo ?? (_GeneralPartyInfo = new GeneralPartyInfo(self.Element("GeneralPartyInfo"))); } } GeneralPartyInfo _GeneralPartyInfo; public InsuredOrPrincipalInfo InsuredOrPrincipalInfo { get { return _InsuredOrPrincipalInfo ?? (_InsuredOrPrincipalInfo = new InsuredOrPrincipalInfo(self.Element("InsuredOrPrincipalInfo"))); } } InsuredOrPrincipalInfo _InsuredOrPrincipalInfo; } public class GeneralPartyInfo { XElement self; public GeneralPartyInfo(XElement self) { this.self = self; } public NameInfo NameInfo { get { return _NameInfo ?? (_NameInfo = new NameInfo(self.Element("NameInfo"))); } } NameInfo _NameInfo; public Addr Addr { get { return _Addr ?? (_Addr = new Addr(self.Element("Addr"))); } } Addr _Addr; } public class InsuredOrPrincipalInfo { XElement self; public InsuredOrPrincipalInfo(XElement self) { this.self = self; } public string InsuredOrPrincipalRoleCd { get { return (string)self.Element("InsuredOrPrincipalRoleCd"); } } } public class NameInfo { XElement self; public NameInfo(XElement self) { this.self = self; } public PersonName PersonName { get { return _PersonName ?? (_PersonName = new PersonName(self.Element("PersonName"))); } } PersonName _PersonName; } public class Addr { XElement self; public Addr(XElement self) { this.self = self; } public string Address1 { get { return (string)self.Element("Addr1"); } } public string City { get { return (string)self.Element("City"); } } public string State { get { return (string)self.Element("StateProvCd"); } } public string Zip { get { return (string)self.Element("PostalCode"); } } } public class PersonName { XElement self; public PersonName(XElement self) { this.self = self; } public string Surname { get { return (string)self.Element("Surname"); } } public string GivenName { get { return (string)self.Element("GivenName"); } } } } 

当然我的导出回到我追加的文本文件。

 using System; using System.Collections.Generic; using System.Text; using System.Data; using System.IO; using System.Windows.Forms; namespace xmlCustomReformat { public static class ExportDataTable { public static void Write(DataTable dt, string filePath) { int i = 0; StreamWriter sw = null; try { sw = new StreamWriter(filePath + "\\Acord_Combined.txt", false); for (i = 0; i < dt.Columns.Count-1; i++) { sw.Write(String.Format("{0,-50}",dt.Columns[i].ColumnName)); } sw.Write(dt.Columns[i].ColumnName); sw.WriteLine(); foreach (DataRow row in dt.Rows) { object[] array = row.ItemArray; for (i = 0; i < array.Length - 1; i++) { sw.Write(String.Format("{0,-50}",array[i].ToString())); } sw.Write(array[i].ToString()); sw.WriteLine(); } sw.Close(); } catch (Exception ex) { MessageBox.Show("Invalid Operation : \n" + ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } } } 

现在我仍然需要在执行一些处理之后将数据追加到相同的xml文件中。 我必须将数据去个性化。 所以我假设我只需要做集而不是获取。 尚不确定此过程的语法。 如果您有改进建议,请随时发表评论。