【问题标题】:Loading XML String into datatable将 XML 字符串加载到数据表中
【发布时间】:2012-09-22 20:48:53
【问题描述】:
           string parseData= "<TEST xmlns:dt=\"urn:schemas-microsoft-com:datatypes\"><A dt:dt=\"string\">10</A><B dt:dt=\"string\">20</B></TEST>";

            DataSet ds = new DataSet("Whatev");

            TextReader txtReader = new StringReader(parseData);
            XmlReader reader = new XmlTextReader(txtReader);
            ds.ReadXml(reader);
            DataTable ad = new DataTable("newT");
            ad.ReadXml(reader);

为此,我在广告中得到了空表,在 ds 中得到了三个表。 我所期待的是, 一张表,两列 A 和 B,一行的值为 10 和 20。

我做错了什么?

【问题讨论】:

    标签: c# visual-studio-2010 datatable xml-parsing


    【解决方案1】:

    您只是没有正确使用它。有很多问题:

    1. 您正在从同一个流中读取两次。在第一遍中,流指针位于流的末尾。当它已经结束时,您尝试再次读取它,因此没有其他内容被读取。要么读入你的数据集,要么读入你的数据表,而不是两者兼而有之。或者,如果你真的想的话,至少要回到流的开头。

    2. 您的 XML 格式不正确。它必须采用以下格式:

      <SomeRoot>
          <TableName>
              <ColumnName>ColumnValue</ColumnName>
          </TableName>
          <TableName>
              <ColumnName>AnotherColumnValue</ColumnName>
          </TableName>
      </SomeRoot>
      

      您将无法对任意 XML 使用该方法。

    3. 您的表没有架构集。您需要读入架构或预先设置它。

      var table = new DataTable("TEST");
      table.Columns.Add("A", typeof(string));
      table.Columns.Add("B", typeof(string));
      table.ReadXml(xmlReader);
      

    试试这个:

    var xmlStr = @"<Root>
        <TEST>
            <A>10</A>
            <B>20</B>
        </TEST>
    </Root>";
    var table = new DataTable("TEST");
    table.Columns.Add("A", typeof(string));
    table.Columns.Add("B", typeof(string));
    table.ReadXml(new StringReader(xmlStr));
    

    如果您决定自己解析 XML,LINQ 可以在这里为您提供帮助。

    public static DataTable AsDataTable(XElement root, string tableName, IDictionary<string, Type> typeMapping)
    {
        var table = new DataTable(tableName);
    
        // set up the schema based on the first row
        XNamespace dt = "urn:schemas-microsoft-com:datatypes";
        var columns =
           (from e in root.Element(tableName).Elements()
            let typeName = (string)e.Element(dt + "dt")
            let type = typeMapping.ContainsKey(typeName ?? "") ? typeMapping[typeName] : typeof(string)
            select new DataColumn(e.Name.LocalName, type)).ToArray();
        table.Columns.AddRange(columns);
    
        // add the rows
        foreach (var rowElement in root.Elements(tableName))
        {
            var row = table.NewRow();
            foreach (var column in columns)
            {
                var colElement = rowElement.Element(column.ColumnName);
                if (colElement != null)
                    row[column.ColumnName] = Convert.ChangeType((string)colElement, column.DataType);
            }
            table.Rows.Add(row);
        }
        return table;
    }
    

    然后使用它:

    var xmlStr = @"<Root>
        <TEST xmlns:dt=""urn:schemas-microsoft-com:datatypes"">
            <A dt:dt=""string"">10</A>
            <B dt:dt=""string"">20</B>
        </TEST>
    </Root>";
    var root = XElement.Parse(xmlStr);
    var mapping = new Dictionary<string, Type>
    {
        { "string", typeof(string) },
    };
    var table = AsDataTable(root, "TEST", mapping);
    

    可能有更好的方法来获取数据类型的关联 .NET 类型,但我目前不知道该怎么做,如果我发现了,我会更新。

    【讨论】:

    • 感谢@Jeff Mercado 的回答。 1. 我只是在研究什么是最好的阅读方式。所以,我都尝试了,很明显我做错了。感谢您指出了这一点。我尝试了 2 和 3,效果很好。但是,我唯一的问题是我没有得到您在 3 中显示的 XML 类型。这可能是一个不同的问题,但是,最好的解析方法是什么,string parseData= "1020";这种xml?
    • 我创建了一个新问题...stackoverflow.com/questions/12694701/…
    • 您可以采用两种方法。如果您想要使用ReadXml() 方法,则必须将XML 转换为适当的格式并从中生成模式,以便可以将该模式传递给ReadXmlSchema() 方法。否则,您可以自己解析 XML 以加载模式并填写表格(LINQ 可以帮助您)。您只是想将 那个 XML 加载到表中,还是特别想使用 ReadXml() 方法?
    • 我只想将 那个 XML 加载到表中。
    • 感谢您的回答,这很有帮助。 :)
    猜你喜欢
    • 2012-09-09
    • 1970-01-01
    • 2013-06-22
    • 2020-01-07
    • 2021-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多