Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用linq和C将xml转换为sql#_Sql_Xml_Linq - Fatal编程技术网

使用linq和C将xml转换为sql#

使用linq和C将xml转换为sql#,sql,xml,linq,Sql,Xml,Linq,我有一个来自外部系统的xml文件,看起来像这样 <?xml version="1.0" encoding="UTF-8"?> <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Body> <Element1> <Element2 day="2009-10-18"> <Elemen

我有一个来自外部系统的xml文件,看起来像这样

<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
    <Body>
        <Element1>
            <Element2 day="2009-10-18">
                <Element3 name="Joe">
                    <Element4 time="1">
                        <Element5 amount="0" price="16.58"/>
                    </Element4>
                </Element3>
                <Element3 name="Fred">
                    <Element4 time="5">
                        <Element5 amount="0" price="15.41"/>
                    </Element4>
                </Element3>
            </Element2>
        </Element1>
    </Body>
</Envelope>
day, name, time, amount, price
2009-10-18, Joe, 1, 0, 16.58
2009-10-18, Fred, 5, 0, 15.41

读取xml并将其插入数据库的最佳方式是什么?我一直在玩linq,但到目前为止没有太大成功。

您需要将其插入SQL Server表吗??如果是:什么版本的SQL Server

您可以使用XQuery在SQL Server中轻松地将其分解,并将数据插入表中。使用类似于:

;WITH XMLNAMESPACES('http://schemas.xmlsoap.org/soap/envelope/' AS ns)
SELECT
    @input.value('(/ns:Envelope/ns:Body/ns:Element1/ns:Element2/@day)[1]', 'varchar(50)') AS 'DayElement',
    node.el.value('(@name)[1]', 'varchar(50)') AS 'Name',
    node.el.value('(ns:Element4/@time)[1]', 'int') AS 'Time',
    node.el.value('(ns:Element4/ns:Element5/@amount)[1]', 'decimal(15,2)') AS 'Amount',
    node.el.value('(ns:Element4/ns:Element5/@price)[1]', 'decimal(15,2)') AS 'Price'
FROM
    @input.nodes('/ns:Envelope/ns:Body/ns:Element1/ns:Element2/ns:Element3') AS node(el)
Day         Name    Time    Amount   Price
2009-10-18  Joe       1      0.00    16.58
2009-10-18  Fred      5      0.00    15.41
这将为您提供如下输出:

;WITH XMLNAMESPACES('http://schemas.xmlsoap.org/soap/envelope/' AS ns)
SELECT
    @input.value('(/ns:Envelope/ns:Body/ns:Element1/ns:Element2/@day)[1]', 'varchar(50)') AS 'DayElement',
    node.el.value('(@name)[1]', 'varchar(50)') AS 'Name',
    node.el.value('(ns:Element4/@time)[1]', 'int') AS 'Time',
    node.el.value('(ns:Element4/ns:Element5/@amount)[1]', 'decimal(15,2)') AS 'Amount',
    node.el.value('(ns:Element4/ns:Element5/@price)[1]', 'decimal(15,2)') AS 'Price'
FROM
    @input.nodes('/ns:Envelope/ns:Body/ns:Element1/ns:Element2/ns:Element3') AS node(el)
Day         Name    Time    Amount   Price
2009-10-18  Joe       1      0.00    16.58
2009-10-18  Fred      5      0.00    15.41

当然,您可以使用它将数据提供给插入dbo.MyTable()的
语句,…
语句,从而立即将数据存储到表中

为那些可能对类似解决方案感兴趣的人添加更多内容

            XDocument doc = XDocument.Load(@"myxml.xml");
            DataContext bt = new DataContext();

            var docxml = from c in doc.Elements("Envelope").Elements("Body").Elements("Element1").Elements("Element2").Elements("Element3")

                     select new mytable()
                     {
                         MyKey = Guid.NewGuid(),
                         day = Convert.ToDateTime(c.Parent.Attribute("day").Value),
                         name = c.FirstAttribute.Value,
                         time = Convert.ToInt32(c.Element("Element4").FirstAttribute.Value),
                         price = Convert.ToDecimal(c.Element("Element4").Element("Element5").Attribute("price").Value),
                         amount = Convert.ToDecimal(c.Element("Element4").Element("Element5").Attribute("amount").Value)

                     };

            bt.mytable.InsertAllOnSubmit(docxml);
            bt.SubmitChanges();

我有有用的开源XLinq扩展和其他UTIL,它们简化了xml解析、数据库持久化、文本序列化POCO类等 详情如下:

    //source code for this example available at: 
    //http://code.google.com/p/servicestack/source/browse/trunk/Common/ServiceStack.Common/ServiceStack.Common.Tests/Xlinq/XlinqExtensionsTests.cs
    public class XmlData : IHasId<int>
    {
      [AutoIncrement]
      public int Id { get; set; }
      public string Day { get; set; }
      public string Name { get; set; }
      public int Time { get; set; }
      public int Amount { get; set; }
      public decimal Price { get; set; }
    }

    [Test]
    public void Insert_data_from_xml_into_db()
    {
      //OrmLiteConfig.DialectProvider = SqlServerOrmLiteDialectProvider.Instance;
      OrmLiteConfig.DialectProvider = SqliteOrmLiteDialectProvider.Instance;

      var element2 = XElement.Parse(xml).AnyElement("Body").AnyElement("Element1").AnyElement("Element2");

      using (var db = ":memory:".OpenDbConnection())
      using (var dbCmd = db.CreateCommand())
      {
        dbCmd.CreateTable<XmlData>(true);
        foreach (var element3 in element2.AllElements("Element3"))
        {
          var xmlData = new XmlData {
            Day = element2.AnyAttribute("day").Value,
            Name = element3.AnyAttribute("name").Value,
            Time = int.Parse(element3.FirstElement().AnyAttribute("time").Value),
            Amount = int.Parse(element3.FirstElement().FirstElement().AnyAttribute("amount").Value),
            Price = decimal.Parse(element3.FirstElement().FirstElement().AnyAttribute("price").Value),
          };
          dbCmd.Insert(xmlData);
        }
        dbCmd.Select<XmlData>().ForEach(x => Console.WriteLine(StringSerializer.SerializeToString(x)));
      }
    }

//Prints out:
//{Id:1,Day:2009-10-18,Name:Joe,Time:1,Amount:0,Price:16.58}
//{Id:2,Day:2009-10-18,Name:Fred,Time:5,Amount:0,Price:15.41}
//此示例的源代码位于:
//http://code.google.com/p/servicestack/source/browse/trunk/Common/ServiceStack.Common/ServiceStack.Common.Tests/Xlinq/XlinqExtensionsTests.cs
公共类XmlData:IHasId
{
[自动增量]
公共int Id{get;set;}
公共字符串Day{get;set;}
公共字符串名称{get;set;}
公共整数时间{get;set;}
公共整数金额{get;set;}
公共十进制价格{get;set;}
}
[测试]
public void将\u数据\u从\u xml\u插入到\u db()中
{
//OrmLiteConfig.DialogyProvider=SqlServerOrmLiteDialectProvider.Instance;
OrmLiteConfig.DialogProvider=SqliteOrmLiteDialectProvider.Instance;
var element2=XElement.Parse(xml).AnyElement(“Body”).AnyElement(“Element1”).AnyElement(“element2”);
使用(var db=“:memory:”.OpenDbConnection())
使用(var dbCmd=db.CreateCommand())
{
dbCmd.CreateTable(true);
foreach(var element3 in element2.等位基因(“element3”))
{
var xmlData=新的xmlData{
Day=element2.AnyAttribute(“Day”).Value,
Name=element3.AnyAttribute(“Name”).Value,
Time=int.Parse(element3.FirstElement().AnyAttribute(“Time”).Value),
Amount=int.Parse(element3.FirstElement().FirstElement().AnyAttribute(“Amount”).Value),
Price=decimal.Parse(element3.FirstElement().FirstElement().AnyAttribute(“Price”).Value),
};
dbCmd.Insert(xmlData);
}
dbCmd.Select().ForEach(x=>Console.WriteLine(StringSerializer.SerializeToString(x));
}
}
//打印出:
//{Id:1,日期:2009-10-18,姓名:乔,时间:1,金额:0,价格:16.58}
//{Id:2,日期:2009-10-18,姓名:Fred,时间:5,金额:0,价格:15.41}

答案将在很大程度上取决于您是否需要代码来构建表结构,或者只是将数据插入到预先存在的表中。谢谢Robert,我需要将数据插入到预先存在的表中。很有趣,但我认为我上面添加的解决方案更简单,不需要额外的组件。同意,但是,我认为在处理数据时要用它的强类型、易测试性、便携性(即非供应商专用性)和可重用性等来处理数据,这是一个很好的做法。上述示例仅适用于SQLServer的特定版本(即2005 +)。这是一个完整的工作版本,代码中只有1个附加组件。我把它和错误的答案作了比较。是的,您的代码(很好),但不完整,需要生成Linq2Sql模型、配置、Sql Server中的现有表,等等-我的不需要。