0
           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);

このために、adで空のテーブルを取得し、dsで3つのテーブルを取得しています。私が期待しているのは、AとBの2つの列を持つ1つのテーブルと、値が10と20の1つの行です。

私は何が間違っているのですか?

4

1 に答える 1

3

あなたは単にそれを正しく使用していません。多くの問題があります:

  1. 同じストリームから2回読み取っています。最初のパスでは、ストリームポインタはストリームの最後にあります。すでに最後になっているときにもう一度読み込もうとするため、他に何も読み取られません。データセットまたはデータテーブルのいずれかに読み込みます。両方ではありません。または、本当に必要な場合は、少なくともストリームの最初に戻ってください。

  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型を取得するためのより良い方法はおそらくありますが、現時点ではその方法がわかりません。見つかった場合は更新します。

于 2012-10-02T00:55:01.330 に答える