昨年、私はXMLベースのWebアプリケーションをDelphiで開発しようとして多くの時間を費やしました。最初のアイデアは美しいものでしたが、その結果、物事は非常に単純だったということでした。その理由の一部は、XMLとオブジェクト間のデータバインディングの実装が面倒すぎるためです(もう1つの部分は、XSLTに精通しておらず、それを学ぶのに多くの時間がかかることです)。
私は常にDelphiによって提供されるXMLデータバインディングを使用しています。最初のツール(XMLSPYなど)を使用して、XMLスキーマ(XSD)を作成し、XMLデータバインディングを使用してDelphiインターフェイスとクラスを生成します。もちろん、プログラムで生成されると、このインターフェイスを操作する必要があります。しかし、問題は、プログラムの開発プロセス中に常にいくつかの変更があることです。XMLSPYを同時に変更し、XMLデータバインドウィザードで再度実行する必要があります。とても面倒です。
したがって、データセットの客観化を考えると、RTTIを使用してオブジェクトのXML永続性を実装できるとすぐに思います。実際、Delphi6で開始されたSOAP実装は、RTTIを使用してSOAPデータへの変換を実装することです(つまり、xml)。明らかに、私はすでに非常に遅れていました。「The Poffient Delphi rtti-複数の開発言語を理解するために必要なパーティーとリンク」で、私の友人であるLex Chowは私にこれをしたと答えました。数年前に働き、私はすぐに彼にソースコードを求めました。 Lexlibは、.NETの基本的なクラスライブラリに似ている多くの機能を備えたライブラリです(もちろん、それほど大きな ^o ^ではありません)。私はこの部分のみが必要なので、このライブラリ全体を使用する必要はありません。そのため、Lexlibを参照し、「DelphiのRTTIを使用してデータセットの単純な客観化を使用する」で実装した部分と組み合わせて、成し遂げる:
TMXMLPersistent = class(TObject) public class PRocedure LoadObjFromXML( aNode : IXMLNode; aObj : TPersistent ); class Procedure SaveObjToXML( aNode : IXMLNode; aObj : TPersistent ); end;const DefaultFilter : TTypeKinds = [tkInteger, tkChar, tkEnumeration, tkFloat, tkString 、TKWCHAR、TKWSTRING、TKINT64]; {TMXMLPERSISTENT}クラス手順; aobjはtmdatasetproxyです)(aobj as tmdatasetproxy)。 ; if(pinfo^.proptype^.kind = tkclass)からtmpobj:= tobums(getPropvalue(aobj、pinfo^.name)) anode.childnodes [widestring(pinfo^.name)]、tmpobj as tpersistent); Pinfo^.NAME)。 ppropinfo; tmpobj:tobject(aobj is tmdatasetproxy)then(aobj as tmdatasetproxy)。 Pinfo:= plist.props [i]; (tmpobj is tpersistent))then saveobjtoxml(anode.addchild(pinfo^.name))、tmpobj as tpersistent if(defaultfilter); ^ .NAME)。この実装は非常に簡単であると言われるべきです。主に3つの部分があります(負荷と保存の構造は似ています):
まず、TMDATASETPROXYに特別な処理が行われ、このクラスが一般的なクラスとは異なるため、すべてのレコードを通過する必要があります。 。
2つ目は、クラスを再帰的に処理することであり、もちろんtpersistentから派生したクラスのみをサポートします。
第三に、一般フィールドは単に弦に変換されて保存されます。これにより、lexlibのフィルターが貸し出され、単純にストリングに変換できるデータ型のみを処理し、変換エラーを引き起こす可能性のあるタイプをフィルタリングします。
上記のコードで使用されているTMProplistについては、「DelphiのRTTIを使用してデータセットを実装する」の実装を参照してください。
以下は、TMDATASETProxyで実装されたデータセットのXML持続性です。 TclientDatasetの使用の問題を排除し、Nodeでフィールドを記録する方法も使用します。この方法で生成されたXMLファイルはわずかに大きくなりますが、特に私がWebアプリケーションで使用することを計画しているXMLは、XSLTを使用する場合ははるかに便利です。
手順tmdatasetproxy.loadfromxml(ixmlnode); ChildNodes [j]; for for fproplist.pinfo:= fproplist.props [i]; [Pinfo^.Name); foreachはprow:= anode.addchild( 'row'); )その後、addchild(sinfo^.name):= getVariant(i);
以下は、データセットのXML持続性を含む単純なデモです。 LOADの場合、従業員はこれらのフィールドタイプを含むテーブルに接続されているAdodataset2に接続されていますが、コンテンツは空で、EmployeeDの身元が削除されます。負荷が完了すると、従業員テーブルのこれらのフィールドの内容がこのテーブルにコピーされます。
Tdemocompany = classisted:fcode:integer:spection tform1.saveclick(tobject); var Demo:= tdemocompany.create; Xmldocument1. = TMXMLPERSISTENT.SMLDOCUMENT1.ADDCHILD、 demo.employee:= nil.free; end; loadclick(sunder:tobject); xmldocument1. = true;テキスト:= inttostr(demo.code); subiTems.datems.add; .Free;
最後に、厄介なXMLデータバインディングに別れを告げることができます。将来XSDを書く必要はありません。便利なツールはありますが、トラブルを節約する方が良いです。