当XML的节点名称相同时,将XML数据插入SQL数据库

时间:2019-04-26 04:23:44

标签: c# .net xml visual-studio

我是C#的新手,我正在用C#开发一个代码,该代码从具有XML格式数据的变量中读取数据。

某些节点正在重复,而我的代码仅读取重复节点的第一条记录。

我的XML示例:

<Stores>
    <Products>
        <Size>Small</Size>
        <ShortName>Coke</ShortName>
        <Id>000001</Id>
        <Description>Drinks</Description>
        <OptionalItemIds>100001</OptionalItemIds>
        <OptionalItemIds>100002</OptionalItemIds>
        <OptionalItemIds>100003</OptionalItemIds>
        <OptionalItemIds>100004</OptionalItemIds>
        <OptionalItemIds>100005</OptionalItemIds>
        <Calories>0</Calories>
        <Name>Diet Coke</Name>
    </Products>
</Stores>

我尝试过的代码片段:

var ProductList = doc.Root.Elements("Products").Select(element => new JMMEntity
            {
                Size = (element.HasElements == true && element.Element("Size") != null) ? element.Element("Size").Value : String.Empty,
                ShortName = (element.HasElements == true && element.Element("ShortName") != null) ? element.Element("ShortName").Value : String.Empty,
                Id = (element.HasElements == true && element.Element("Id") != null) ? element.Element("Id").Value : String.Empty,
                Description = (element.HasElements == true && element.Element("Description") != null) ? element.Element("Description").Value : String.Empty,
                OptionalItemIds = (element.HasElements == true && element.Element("OptionalItemIds") != null) ? element.Element("OptionalItemIds").Value : String.Empty,
                Calories = (element.HasElements == true && element.Element("Calories") != null) ? element.Element("Calories").Value : String.Empty,
                Name = (element.HasElements == true && element.Element("Name") != null) ? element.Element("Name").Value : String.Empty
            }).ToList();

var xmlNode_Product = new XElement("Stores",
           from Product in ProductList
           select new XElement("Products",
                          new XElement("Size", Product.Size),
                          new XElement("ShortName", Product.ShortName),
                          new XElement("Id", Product.Id),
                          new XElement("Description", Product.Description),
                          new XElement("OptionalItemIds", Product.OptionalItemIds),
                          new XElement("Calories", Product.Calories),
                          new XElement("Name", Product.Name)
                      ));

接下来,我将调用此存储过程以将数据输入数据库:

INSERT INTO Products(Size, ShortName, Id, Description, OptionalItemIds, Calories, Name)
    SELECT  
        tbl.Stores.value('Size[1]', 'nvarchar(20)') AS Size,
        tbl.Stores.value('ShortName[1]', 'nvarchar(20)') AS ShortName,
        tbl.Stores.value('Id[1]', 'nvarchar(250)') AS Id,
        tbl.Stores.value('Description[1]', 'nvarchar(20)') AS Description,
        tbl.Stores.value('OptionalItemIds.[1]', 'nvarchar(250)') AS OptionalItemIds,      
        tbl.Stores.value('Calories[1]', 'nvarchar(20)') AS Calories,
        tbl.Stores.value('Name[1]', 'nvarchar(20)') AS Name
    FROM 
        @XmlProduct.nodes('/Stores/Products') AS tbl(Stores);

我得到的结果:

    Size    ShortName   ID    Description   OptionalItemIds Calories    Name
    Small   Coke        000001  Drinks          100001           0       Diet Coke

预期结果:

    Size    ShortName   ID    Description   OptionalItemIds Calories    Name
    Small   Coke        000001  Drinks          100001           0       Diet Coke
    Small   Coke        000001  Drinks          100002           0       Diet Coke
    Small   Coke        000001  Drinks          100003           0       Diet Coke
    Small   Coke        000001  Drinks          100004           0       Diet Coke
    Small   Coke        000001  Drinks          100005           0       Diet Coke

2 个答案:

答案 0 :(得分:0)

您需要使用CROSS APPLY并分别获取<OptionalItemIds>的枚举-尝试执行以下操作:

INSERT INTO Products(Size, ShortName, Id, Description, OptionalItemIds, Calories, Name)
    SELECT  
        tbl.Stores.value('Size[1]', 'nvarchar(20)') AS Size,
        tbl.Stores.value('ShortName[1]', 'nvarchar(20)') AS ShortName,
        tbl.Stores.value('Id[1]', 'nvarchar(250)') AS Id,
        tbl.Stores.value('Description[1]', 'nvarchar(20)') AS Description,
        -- tbl.Stores.value('OptionalItemIds.[1]', 'nvarchar(250)') AS OptionalItemIds,      
        tbl2.ItemIds.value('.', 'int') AS OptionalItemId,
        tbl.Stores.value('Calories[1]', 'nvarchar(20)') AS Calories,
        tbl.Stores.value('Name[1]', 'nvarchar(20)') AS Name
    FROM 
        @XmlProduct.nodes('/Stores/Products') AS tbl(Stores)
    -- get the list of "OptionalItemIds" separately, cross apply to produce rows to be inserted
    CROSS APPLY
        @XmlProduct.nodes('/Stores/Products/OptionalItemIds') AS tbl2(ItemIds)
;

答案 1 :(得分:0)

此代码对我有用,

    INSERT INTO Products(Size, ShortName, Id, Description, OptionalItemIds, Calories, Name)
SELECT  
    tbl.Stores.value('Size[1]', 'nvarchar(20)') AS Size,
    tbl.Stores.value('ShortName[1]', 'nvarchar(20)') AS ShortName,
    tbl.Stores.value('Id[1]', 'nvarchar(250)') AS Id,
    tbl.Stores.value('Description[1]', 'nvarchar(20)') AS Description,     
    tbl2.ItemIds.value('.', 'nvarchar(20)') AS OptionalItemIds,
    tbl.Stores.value('Calories[1]', 'nvarchar(20)') AS Calories,
    tbl.Stores.value('Name[1]', 'nvarchar(20)') AS Name
FROM 
    @XmlProduct.nodes('/Stores/Products') AS tbl(Stores)
CROSS APPLY tbl.Stores.nodes('OptionalItemIds') AS tbl2(ItemIds)