XE5からXE6以降へプロジェクトを移行したとき、TFDMemTableが入出力するXMLの互換性
問題
TFDMemTableコンポーネントには、LoadFromFile、SaveToFileメソッドを用いてデータセットをXML形式、バイナリ形式、JSON形式(XE5は未対応)等のフォーマットで入出力する機能があります。例えば、TFDMemTableで書き出したXMLファイルをTFDMemTableで読み込むことができます。
しかしながら、XE5のTFDMemTableが入出力するXMLとXE6のTFDMemTableが入出力するXMLは、XE6で一部のXMLスキーマの仕様が変更されているため、両バージョン間で互換性がありません。例えば、XE5で書き出したXMLファイルをXE6で読み込もうとすると、以下のようなエラーが発生します。
原因
XE5とXE6で出力されるXML内のオブジェクトを比較すると、以下のような違いがあります。
XE5では、
<TableRowList_Updates>
..
</TableRowList_Updates>
XE6では、
<TableRowList>
..
</TableRowList>
実はXE5=>XE6のバージョンアップに伴い、FireDACでは、クラス名、ユニット名、プロパティ名等に対して一部リファクタリングが行なわれております。もともと、XE5に存在した「FireDAC.DatS.TFDDatSTableRowList_Updates」というクラスが XE6ではRemoveされ、「FireDAC.DatS.TFDDatSTableRowList」へ統一されております。このリファクタリングがSaveToFileによって出力されるXMLのオブジェクトにも影響いたします。
そして、その結果、XE6では「TableRowList_Updates」というオブジェクトではなく、「TableRowList」というオブジェクトがXML内に存在することを期待しているため、XE5で出力したXMLファイルは読み込みに失敗してしまいます。
解決
XE5とXE6のXMLのフォーマットには、一部互換性の無いオブジェクトが含まれているため、 XE6でXMLファイルを読み込むための対処方法は、以下の通りです。
- XE6で再度、同じ内容のデータをXMLファイルへ出力し直す
- XE5で書き出したXMLファイルをエディタで開いて、XMLファイルのスキーマの文字列を置換する
以下は、XE5で出力したXMLファイルの修正例です。
修正前:
<?xml version="1.0" encoding="utf-8"?>
<FDBS Version="9">
<Manager UpdatesRegistry="True">
<TableList>
<Table Name="FDMemTable1" TabID="0" EnforceConstraints="False" MinimumCapacity="50" CheckNotNull="False">
<ColumnList>
<Column Name="Field1" SourceID="1" DataType="WideString" Size="20" Searchable="True" AllowNull="True" Base="True" OAllowNull="True" OInUpdate="True" OInWhere="True" OriginColName="Field1" SourceSize="20"/>
<Column Name="Field2" SourceID="2" DataType="Int32" Searchable="True" AllowNull="True" Base="True" OAllowNull="True" OInUpdate="True" OInWhere="True" OriginColName="Field2"/>
</ColumnList>
<ConstraintList Enforce="False"/>
<ViewList/>
<TableRowList_Updates>
<Row RowID="0" RowState="Unchanged">
<Original Field1="testdata" Field2="1"/>
</Row>
</TableRowList_Updates>
</Table>
</TableList>
<RelationList/>
<UpdatesJournal SavePoint="1"/>
</Manager>
</FDBS>
修正後:
<?xml version="1.0" encoding="utf-8"?>
<FDBS Version="9">
<Manager UpdatesRegistry="True">
<TableList>
<Table Name="FDMemTable1" TabID="0" EnforceConstraints="False" MinimumCapacity="50" CheckNotNull="False">
<ColumnList>
<Column Name="Field1" SourceID="1" DataType="WideString" Size="20" Searchable="True" AllowNull="True" Base="True" OAllowNull="True" OInUpdate="True" OInWhere="True" OriginColName="Field1" SourceSize="20"/>
<Column Name="Field2" SourceID="2" DataType="Int32" Searchable="True" AllowNull="True" Base="True" OAllowNull="True" OInUpdate="True" OInWhere="True" OriginColName="Field2"/>
</ColumnList>
<ConstraintList Enforce="False"/>
<ViewList/>
<TableRowList>
<Row RowID="0" RowState="Unchanged">
<Original Field1="testdata" Field2="1"/>
</Row>
</TableRowList>
</Table>
</TableList>
<RelationList/>
<UpdatesJournal SavePoint="1"/>
</Manager>
</FDBS>