使用 Linq 从 IEnumerable<XElement> 中提取并存储在数据表中 [英] Using Linq to pull from IEnumerable&lt;XElement&gt; and store in data table

查看:31
本文介绍了使用 Linq 从 IEnumerable<XElement> 中提取并存储在数据表中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a datatable that looks like the following

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 中读取信息并将该特定数据存储到我的数据表中.我为每个报价"创建了一个单独的 xml 文件,因此我将在数据表中添加一个新行.我关心的xml部分如下:

My goal is to read information in from an xml and store that specific data into my datatable. I have a separate xml file for each "Quote" so I will be appending a new row to the datatable. The part of the xml I am concerned with is as follows:

    '- <ACORD>
    - <SignonRq>
    - <SignonPswd>
    - <CustId>
      <SPName>com.agencyport</SPName> 
      </CustId>
    - <CustPswd>
      <EncryptionTypeCd>NONE</EncryptionTypeCd> 
      <Pswd>default</Pswd> 
      </CustPswd>
      </SignonPswd>
      <ClientDt>2006-04-04T15:44:00</ClientDt> 
      <CustLangPref>en-US</CustLangPref> 
    - <ClientApp>
      <Org>Applied Systems</Org> 
      <Name>WinTam</Name> 
      <Version>7.1.0</Version> 
      </ClientApp>
      </SignonRq>
    - <InsuranceSvcRq>
      <RqUID>81913CB5-3EAB-F158-EE24-5910F9BE9C26</RqUID> 
    - <PersAutoPolicyQuoteInqRq>
      <RqUID>7B010E52-44F2-487A-521B-9D1E3500C23D</RqUID> 
    - <Producer id="AB4E95FF02FA91FAA4D7A2D96B59D8866A">
    - <ProducerInfo id="AF04551B40F1439BCCC77CA3A21165FFAA">
      <ContractNumber id="AD2178F32385016684F33F848830CAA18A">AP</ContractNumber> 
      </ProducerInfo>
      </Producer>

<InsuredOrPrincipal id="A498E0A503206279EE434988B68472974A">
                <GeneralPartyInfo id="A4F0BBE53B311050FD0552BB41090A523A">
                    <NameInfo id="AFBDE1032EEEA0821374C7C9428B0B44CA">
                        <PersonName id="A883A5BFD8FA8E71F52780B1E678AD64AA">
                            <Surname id="A40A625346687D257582BF6499710839BA">TEST</Surname>
                            <GivenName id="A021FD886DAAF628327F542786B6CD9B5A">TEST</GivenName>
                            <OtherGivenName id="A06DB1E21AF9BD37420B5C39E6562C78AA">TEST</OtherGivenName>
                        </PersonName>
                        <TaxIdentity id="ABC2680C3B21A161E54BCDBA78DFCCE77A">
                            <TaxIdTypeCd id="A050BE41EE9F2B1C713E934B1D6D2B31BA">SSN</TaxIdTypeCd>
                        </TaxIdentity>
                    </NameInfo>
                    <Addr id="A0C5DF11BD2CF70669AE368F685DAD141A">
                        <AddrTypeCd id="A82658A7F5CEB14239A4023874F594FC9A">MailingAddress</AddrTypeCd>
                        <Addr1 id="A0DC5C008818A7559527AD40AB1E0D8E0A">100 MAIN ST</Addr1>
                        <City id="A7DBC851540752437C649745A63508198A">Howell</City>
                        <StateProvCd id="ACDF462092E91668AD7996C662ACC1622A">MI</StateProvCd>
                        <PostalCode id="A45C6341382A3314D1EC79FEF20FE9D82A">48843</PostalCode>
                        <CountryCd id="AD69C7B00BB7F210588E016FF281675F6A">Livingston</CountryCd>
                    </Addr>
                    <Communications id="AFC53B2B003342664BE4635C38C7C6C45A">
                        <PhoneInfo id="AE5497FDB30717F033E8DFA47B3A36142A">
                            <PhoneTypeCd id="AF8662F35A8F1FD3DD993CECB53EB2FCAA">Phone</PhoneTypeCd>
                            <CommunicationUseCd id="ADA98E4A9B820C002189B1124F071D462A">Home</CommunicationUseCd>
                            <PhoneNumber id="A7F0F2A55F636FB6DCED2F6815271B352A">313-272-6576</PhoneNumber>
                        </PhoneInfo>
                    </Communications>
                </GeneralPartyInfo>
                <InsuredOrPrincipalInfo id="A09004254D9A7BE38EA45B20CCD6A0EC2A">
                    <InsuredOrPrincipalRoleCd id="A2B16D7C6D9CE94DB83DDC6C69BE52BDBA">Insured</InsuredOrPrincipalRoleCd>
                    <PersonInfo id="AE7CB4EE90C6BEBB1C79DF10415B3B8E5A">
                        <MiscParty id="A3AC37CD29B32FA46D0204601CE86F0C0A">
                            <MiscPartyInfo id="A5A9326BB8C3E68900D23F62420A06362A">
                                <MiscPartyRoleCd id="A92E022991F988677D6EF8434207DDEBBA">Employer</MiscPartyRoleCd>
                            </MiscPartyInfo>
                        </MiscParty>
                    </PersonInfo>
                </InsuredOrPrincipalInfo>
            </InsuredOrPrincipal>

到目前为止我想出的是:

What I have come up with so far is this:

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<XElement> 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 文件访问数据并将其存储在我的数据表中的最有效方法.我试过如下循环数据:

This method is inside of a Class so you can assume getting the file and everything works just fine. I just need to know the most efficient way of accessing the data from the xml file and storing it in my datatable. I'v tried looping data as follows:

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

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

I just dont know enough about xml to know how to access it.Thanks again and If you need more information please let me know. **

推荐答案

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

I prefer creating objects for each node level. It is easier to debug and test.

使用这个 xml 库.

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

You'd create classes for each part, like:

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

根据您的需要,您可以根据需要扩大或缩小课程的数量和每个课程的信息,但这是我的做法,因为它对我更有意义.

Depending on your needs you can expand or shrink the number of classes and information per class as you need, but this is the way I'd go about it, as it makes more sense to me.

使用此代码进行测试:

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

这给了我预期的输出:

<?xml version="1.0" encoding="utf-8"?>
<InsuredOrPrincipal>
  <GeneralPartyInfo>
    <NameInfo>
      <PersonName>
        <Surname>Surname</Surname>
      </PersonName>
    </NameInfo>
  </GeneralPartyInfo>
</InsuredOrPrincipal>

这篇关于使用 Linq 从 IEnumerable<XElement> 中提取并存储在数据表中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆