通常、私はDataSet
s とDataTable
s を避けるようにしていますが、現在、それらを使用することが理にかなっていると思われる要件があります。
名前にスペースが含まれていて、列の型が私が書いたカスタム型であるDataTable
場合、 a のシリアライズに問題があります。DataColumn
シリアル化プロセスが、エンコードされた列名に誤ってエスケープ文字を追加しているようです。まるで 2 回エンコードされたかのようです。列のデータ型として独自の型を使用した場合にのみ発生し、正常にtypeof(object)
動作します。
これは標準機能ですか?もしそうなら、誰かがそれを回避する方法を知っていますか?
次のコード サンプルは、この問題を示しています。「NameWithoutSpaces」という列は「NameWithoutSpaces」と同じようにエンコードされますが、「Name With Spaces」は余分なx005F文字を含む「Name_x005F_x0020_With_x005F_x0020_Spaces」としてエンコードされます。
スキーマを書き出すと、列は「Name_x0020_With_x0020_Spaces」として正しくエンコードされます。これは、Read* メソッドが呼び出されるとこの列が空白になるため、問題の原因であると推測されます。
XmlConvert.EncodeNameのドキュメントによると、スペースはx0020でエンコードする必要があり、005Fはエスケープ文字として使用されます。したがって、得られた結果は、テキストがこのメカニズムによって 2 回エンコードされた場合にどうなるかのようです。
namespace DataTableSerialization
{
using System.Data;
class Program
{
static void Main(string[] args)
{
var dataTable = CreateDataTable();
var row1 = dataTable.NewRow();
row1.ItemArray = new object[] { new Item {Value = "Data1"}, new Item {Value = "Data2"} };
dataTable.Rows.Add(row1);
dataTable.WriteXml(@"C:\datatable.xml");
dataTable.WriteXmlSchema(@"C:\schema.xml");
var dataTable2 = new DataTable();
dataTable2.ReadXmlSchema(@"C:\schema.xml");
dataTable2.ReadXml(@"C:\datatable.xml");
}
private static DataTable CreateDataTable()
{
var table = new DataTable { TableName = "Table" };
var col1 = new DataColumn("NameWithoutSpaces", typeof(Item));
var col2 = new DataColumn("Name With Spaces", typeof(Item));
table.Columns.Add(col1);
table.Columns.Add(col2);
return table;
}
}
public class Item
{
public string Value { get; set; }
}
}