【问题标题】:Data in a XML node into a table将 XML 节点中的数据放入表中
【发布时间】:2011-08-09 23:55:09
【问题描述】:

编辑:

 <people>
        <person>
            <name>John Doe</name>
            <age>21</age>
        </person>
        <person>
            <name>Jane Smith</name>
            <age>24</age>
        </person>
    </people>

实际上我想知道的是如何使用 xpath 同时获取姓名和年龄。 我可以使用

检索名称
string fileName = "testinfo.xml";
            XPathDocument doc = new XPathDocument(fileName);

            XPathNavigator nav = doc.CreateNavigator();
            XPathExpression expr;
            expr = nav.Compile("/People/Person/name");
            XPathNodeIterator iterator = nav.Select(expr);

           try{
               while (iterator.MoveNext())
            {

                XPathNavigator nav2 = iterator.Current.Clone();
                Console.WriteLine("name" + nav2.Value);

            }
            }
catch(Exception ex) 
{
   Console.WriteLine(ex.Message);
}

我需要通过只遍历 xml 节点一次来获取 while 循环中的姓名和年龄。 抱歉没说清楚。

【问题讨论】:

  • 必须使用 xpath? Linq to XML 不是一个选项?

标签: .net sql-server xpath xml-parsing


【解决方案1】:

首先,关于您的问题的几个问题:

您的 XML 示例并不适合简单回答。让我们把它改成对语义更友好的东西(这是一个词吗?):

<people>
    <person>
        <name>John Doe</name>
        <age>21</age>
    </person>
    <person>
        <name>Jane Smith</name>
        <age>24</age>
    </person>
</people>

您的问题并未真正提及 尝试解决问题的方法。正如 NovaJoe 所说,使用 Linq-to-XML 和 Linq-to-SQL 进行编码将非常简单,那么更喜欢如何与数据库交互呢?您过去是否编写过 C# 代码来连接数据库?你熟悉 LINQ 吗? (如果没有,你应该学习它!

为了说服您学习上述技术有多糟糕,如果您还不熟悉它们,我使用出色的程序 @ 制作了一个 Linq-to-XML 和 Linq-to-SQL 的快速示例987654321@:

我有以下数据库表:

CREATE TABLE [dbo].[People]
(
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Name] [varchar](max) NOT NULL,
    [Age] [int] NOT NULL,
    CONSTRAINT [PK_People] PRIMARY KEY CLUSTERED 
    (
        [Id] ASC
    )
    WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

我使用 LinqPAD 为我打开了一个标准的 Linq-to-SQL 连接:

最后是 C# 代码:

// Connect to the database using linq-to-sql
var db = new TypedDataContext();

// Load the xml file using linq-to-xml
var doc = XDocument.Load(@"C:\path\to\file\people.xml");
var people = doc.Descendants("person");
foreach (var person in people)
{
    // Create person object
    var personObject = new People();
    personObject.Name = person.Descendants("name").Single().Value;
    personObject.Age = Convert.ToInt32(person.Descendants("age").Single().Value);
    // Queue to add person to database
    db.People.InsertOnSubmit(personObject);
}

// Finally, submit any pending changes
db.SubmitChanges();

这导致以下数据进入我的数据库:

【讨论】:

    【解决方案2】:

    你没有告诉我们你想怎么做 - 存储过程?来自您的应用程序的即席 SQL 查询?你的桌子是什么样子的??

    根据您的输入,您可以使用此 SQL XQuery 表达式将其解析为“伪表”或行和列:

    DECLARE @input XML = '<element1>
        <element2>
            <element3>b</element3>
            <element4>c</element4>
        </element2>
        <element2>
            <element3>b</element3>
            <element4>c</element4>
        </element2>
    </element1>'
    
    SELECT
        e2.value('(element3)[1]', 'varchar(50)') AS 'Element3',
        e2.value('(element4)[1]', 'varchar(50)') AS 'Element4'
    FROM
        @input.nodes('/element1/element2') AS E1(E2)
    

    这将返回以下输出:

    Element3    Element4
       b           c
       b           c
    

    当然,您也可以基于行/列的输出编写INSERT INTO ....... 语句而不仅仅是SELECT,并将已解析的XML 数据插入到关系表中。你可以例如有一个存储过程,它从您的 C# 应用程序中获取 XML 类型的参数,然后在该存储过程中进行解析并插入到表中。

    【讨论】:

      【解决方案3】:

      这完全取决于您的数据库实现。如果必须这样做,我会使用 Linq-to-XML 从 XML 节点中提取值,然后使用 LINQ-to-SQL 将其推送到数据库中。

      【讨论】:

        【解决方案4】:

        我找到了我要找的人。

         expr = nav.Compile("/people/person/*[self::name or self::age]");
        

        通过上述方法,我可以使用 xpath 同时获取名称和年龄节点。但是我发现你的所有答案都很有趣。

        感谢

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-01-11
          • 2014-03-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多