他のアプリケーションがデータファイルの読み取りと書き込みを行えるように、オブジェクトをXMLとして保存したいと思います。これは、Matlabのバイナリマットファイルでは非常に難しいことです。
私が遭遇している根本的な問題は、Matlabのリフレクション(.NETで同様のことを行うために使用した)に相当するものが、プライベートプロパティに関してあまり機能しないことです。Matlabのstruct(object)
関数は、オブジェクトからXMLを作成するという点で、ハックを提供します。
x = myInstance.myPrivateProperty;
...できます
props = struct(myInstance);
x = props.myPrivateProperty;
したがって、以下のコードを使用して、任意のオブジェクトから純粋な(オブジェクトを含まない)構造体を作成できます。その後、純粋な構造体を使用してXMLファイルを作成するのは簡単です。
しかし、プロセスを逆にする方法はありますか?つまり、以下のコードによって保存されたデータを使用してオブジェクトインスタンスを作成するには(そのデータには、クラスインスタンスのすべての非依存、非定数、非一時プロパティのリスト、およびクラスの名前が含まれます)?私は、すべてのオブジェクトがXmlSerializableというクラスから継承することを考えていました。このクラスは、コンストラクターの単一の引数として構造体を受け入れ、構造体に含まれるすべての値を対応する名前のプロパティに割り当てます。ただし、MyClassがXmlSerializableを継承する場合、XmlSerializableのコードでMyClassのプライベートプロパティを設定することは許可されていないため、これは機能しません(プライベートプロパティを操作するための一般化された関数を作成するにはどうすればよいですか?)。これは.NETでは問題ありません(参照リフレクションで私有財産を設定することはできますか?)、しかし私はMatlabでそれを理解するのに苦労しています。
このコードは、渡されたオブジェクトのすべての状態情報を含み、オブジェクトインスタンスを含まない構造体を作成します。結果の構造体は、XMLに簡単に書き込むことができます。
function s = toPureStruct(thing)
if isstruct(thing)
s = collapseObjects(thing);
s.classname = 'struct';
elseif isobject(thing)
s.classname = class(thing);
warning off MATLAB:structOnObject;
allprops = struct(thing);
warning on MATLAB:structOnObject
mc = metaclass(thing);
for i=1:length(mc.PropertyList)
p = mc.PropertyList(i);
if strcmp(p.Name, 'classname')
error('toStruct:PropertyNameCollision', 'Objects used in toStruct may not have a property named ''classname''');
end
if ~(p.Dependent || p.Constant || p.Transient)
if isobject(allprops.(p.Name))
s.(p.Name) = toPureStruct(allprops.(p.Name));
elseif isstruct(allprops.(p.Name))
s.(p.Name) = collapseObjects(allprops.(p.Name));
else
s.(p.Name) = allprops.(p.Name);
end
end
end
else
error(['Conversion to pure struct from ' class(thing) ' is not possible.']);
end
end
function s = collapseObjects(s)
fnames = fields(s);
for i=1:length(fnames)
f = s.(fnames{i});
if isobject(f)
s.(fnames{i}) = toPureStruct(f);
elseif isstruct(f)
s.(fnames{i}) = collapseObjects(f);
end
end
end
編集:保存されたファイルを読みたい他の「アプリケーション」の1つは、バージョン管理システム(Matlabオブジェクトによって定義された構成のパラメーターの変更を追跡するため)です。したがって、実行可能なソリューションは、人間が理解できるテキストを生成できる必要があります。上記のtoPureStructメソッドは、構造体がXMLに変換されるときにこれを行います。