将XML String加载到datatable中

时间:2012-10-02 00:12:16

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

           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.

我做错了什么?

1 个答案:

答案 0 :(得分:3)

你根本就没有正确使用它。有很多问题:

  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);
    
  4. 请改为尝试:

    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类型,但我现在不知道如何做到这一点,如果我发现它,我会更新。