C# 将XML文件解析为数据表

C# 将XML文件解析为数据表,c#,xml,C#,Xml,我试图将一个XML文件解析为一个数据表,然后将其加载到SQL server数据库中。我的第一步是解析XML 这是示例文件: <Report> <Summary> <Member Name="Krispy Kreme Doughnuts Inc" ID="7003200" /> <BatchFile Name="ftpoobt200303130547" SendingClientName="" ID="000000587" Format="ANSI" Da

我试图将一个XML文件解析为一个数据表,然后将其加载到SQL server数据库中。我的第一步是解析XML

这是示例文件:

<Report>
<Summary>
<Member Name="Krispy Kreme Doughnuts Inc" ID="7003200" />
<BatchFile Name="ftpoobt200303130547" SendingClientName="" ID="000000587" Format="ANSI" Date="2020-03-03 13:06:31" Result="Successful" Creator="STP-KRISPYKREMED" />
<Total NoTransactions="3" /><Success NoTransactions="3" /><Fail NoTransactions="0" /></Summary>
<Transactions><Transaction RequestID="2593" TransactionID="7003534217" Status="Accepted" Date="2020-03-03 13:06:31" DueDate="2021-01-25 00:00:00" Currency="USD" PaymentAmount="25,584.79" SourceAccount="6190000020" SupplierName="JTM Foods LLC" SupplierAccount="6190000080" MessageText="$$" MessageDescription="" />
<Transaction RequestID="2594" TransactionID="7003534218" Status="Accepted" Date="2020-03-03 13:06:31" DueDate="2021-02-25 00:00:00" Currency="USD" PaymentAmount="327,538.77" SourceAccount="6190000020" SupplierName="BakeMark USA" SupplierAccount="6190000060" MessageText="$$" MessageDescription="" />
<Transaction RequestID="2595" TransactionID="7003534219" Status="Accepted" Date="2020-03-03 13:06:31" DueDate="2021-02-25 00:00:00" Currency="USD" PaymentAmount="48,588.70" SourceAccount="6190000020" SupplierName="Bay State Milling Company" SupplierAccount="6190000070" MessageText="$$" MessageDescription="" />
</Transactions></Report>
我可以找到第一个和第二个外部节点(摘要和事务),但不确定如何深入到实际数据。例如,我需要成员节点的名称和值、id和值。这些是数据库中的实际字段。

尝试使用Xml Linq:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Data;
using System.Globalization;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("RequestID", typeof(int));
            dt.Columns.Add("TransactionID", typeof(string));
            dt.Columns.Add("Status", typeof(string));
            dt.Columns.Add("Date", typeof(DateTime));
            dt.Columns.Add("DueDate", typeof(DateTime));
            dt.Columns.Add("Currency", typeof(string));
            dt.Columns.Add("PaymentAmount", typeof(decimal));
            dt.Columns.Add("SourceAccount", typeof(string));
            dt.Columns.Add("SupplierName", typeof(string));
            dt.Columns.Add("SupplierAccount", typeof(string));
            dt.Columns.Add("MessageText", typeof(string));
            dt.Columns.Add("MessageDescription", typeof(string));

            XDocument doc = XDocument.Load(FILENAME);

            Dictionary<string, Dictionary<string, string>> summary = doc.Descendants("Summary").Elements()
                .GroupBy(x => x.Name.LocalName, y => y.Attributes()
                    .GroupBy(a => a.Name.LocalName, b => (string)b)
                    .ToDictionary(a => a.Key, b => b.FirstOrDefault()))
                .ToDictionary(x => x.Key, y => y.FirstOrDefault());


            foreach (XElement transaction in doc.Descendants("Transaction"))
            {
                dt.Rows.Add(new object[] {
                    (int)transaction.Attribute("RequestID"),
                    (string)transaction.Attribute("TransactionID"),
                    (string)transaction.Attribute("Status"),
                    DateTime.ParseExact((string)transaction.Attribute("Date"), "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture),
                    DateTime.ParseExact((string)transaction.Attribute("DueDate"), "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture),
                    (string)transaction.Attribute("Currency"),
                    decimal.Parse((string)transaction.Attribute("PaymentAmount")),
                    (string)transaction.Attribute("SourceAccount"),
                    (string)transaction.Attribute("SupplierName"),
                    (string)transaction.Attribute("SupplierAccount"),
                    (string)transaction.Attribute("MessageText"),
                    (string)transaction.Attribute("MessageDescription")
                });
            }


        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Xml;
使用System.Xml.Linq;
使用系统数据;
利用制度全球化;
命名空间控制台应用程序1
{
班级计划
{
常量字符串文件名=@“c:\temp\test.xml”;
静态void Main(字符串[]参数)
{
DataTable dt=新的DataTable();
添加(“请求ID”,typeof(int));
添加(“TransactionID”,typeof(string));
添加(“状态”,类型(字符串));
添加(“日期”,类型(日期时间));
添加(“DueDate”,typeof(DateTime));
添加(“货币”,类型(字符串));
添加(“付款金额”,类型(十进制));
添加(“SourceAccount”,typeof(string));
添加(“供应商名称”,类型(字符串));
添加(“供应商账户”,类型(字符串));
添加(“MessageText”,typeof(string));
添加(“MessageDescription”,typeof(string));
XDocument doc=XDocument.Load(文件名);
Dictionary summary=doc.substands(“summary”).Elements()
.GroupBy(x=>x.Name.LocalName,y=>y.Attributes()
.GroupBy(a=>a.Name.LocalName,b=>(字符串)b)
.ToDictionary(a=>a.Key,b=>b.FirstOrDefault())
.ToDictionary(x=>x.Key,y=>y.FirstOrDefault());
foreach(文档子体中的XElement事务(“事务”))
{
dt.Rows.Add(新对象[]){
(int)transaction.Attribute(“RequestID”),
(字符串)transaction.Attribute(“TransactionID”),
(字符串)transaction.Attribute(“状态”),
DateTime.ParseExact((字符串)transaction.Attribute(“日期”),“yyyy-MM-dd HH:MM:ss”,CultureInfo.InvariantCulture),
DateTime.ParseExact((字符串)transaction.Attribute(“DueDate”),“yyyy-MM-dd HH:MM:ss”,CultureInfo.InvariantCulture),
(字符串)transaction.Attribute(“货币”),
decimal.Parse((字符串)transaction.Attribute(“PaymentAmount”)),
(字符串)transaction.Attribute(“SourceAccount”),
(字符串)transaction.Attribute(“供应商名称”),
(字符串)transaction.Attribute(“供应商帐户”),
(字符串)transaction.Attribute(“MessageText”),
(字符串)transaction.Attribute(“MessageDescription”)
});
}
}
}
}

一旦xml文件标记达到4到4级,DataTable Read方法会将数据集分割成多个无用的表。此外,您可以使用T-SQL将xml文件直接加载到MS SQL Server中。这对于xml的事务部分非常有效,但对于摘要部分又如何?我需要将其添加到其他表格中吗?您需要汇总表格还是其他格式?我将更新代码以使用字典。当我将其写入数据库时,每条记录将包括摘要和一个事务行。如果我能得到与该模式匹配的最终数据表,那么写入数据库将非常容易。写入数据库的格式是什么?datatable在向数据库添加数据方面没有真正的帮助。有帮助的是,数据被组织在与数据库中的表相匹配的组中。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Data;
using System.Globalization;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("RequestID", typeof(int));
            dt.Columns.Add("TransactionID", typeof(string));
            dt.Columns.Add("Status", typeof(string));
            dt.Columns.Add("Date", typeof(DateTime));
            dt.Columns.Add("DueDate", typeof(DateTime));
            dt.Columns.Add("Currency", typeof(string));
            dt.Columns.Add("PaymentAmount", typeof(decimal));
            dt.Columns.Add("SourceAccount", typeof(string));
            dt.Columns.Add("SupplierName", typeof(string));
            dt.Columns.Add("SupplierAccount", typeof(string));
            dt.Columns.Add("MessageText", typeof(string));
            dt.Columns.Add("MessageDescription", typeof(string));

            XDocument doc = XDocument.Load(FILENAME);

            Dictionary<string, Dictionary<string, string>> summary = doc.Descendants("Summary").Elements()
                .GroupBy(x => x.Name.LocalName, y => y.Attributes()
                    .GroupBy(a => a.Name.LocalName, b => (string)b)
                    .ToDictionary(a => a.Key, b => b.FirstOrDefault()))
                .ToDictionary(x => x.Key, y => y.FirstOrDefault());


            foreach (XElement transaction in doc.Descendants("Transaction"))
            {
                dt.Rows.Add(new object[] {
                    (int)transaction.Attribute("RequestID"),
                    (string)transaction.Attribute("TransactionID"),
                    (string)transaction.Attribute("Status"),
                    DateTime.ParseExact((string)transaction.Attribute("Date"), "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture),
                    DateTime.ParseExact((string)transaction.Attribute("DueDate"), "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture),
                    (string)transaction.Attribute("Currency"),
                    decimal.Parse((string)transaction.Attribute("PaymentAmount")),
                    (string)transaction.Attribute("SourceAccount"),
                    (string)transaction.Attribute("SupplierName"),
                    (string)transaction.Attribute("SupplierAccount"),
                    (string)transaction.Attribute("MessageText"),
                    (string)transaction.Attribute("MessageDescription")
                });
            }


        }
    }
}