Tahun lalu saya menghabiskan banyak waktu mencoba mengembangkan aplikasi web berbasis XML dengan Delphi. Gagasan awalnya indah, tetapi hasilnya adalah hal -hal yang sangat sederhana. Bagian dari alasannya adalah bahwa implementasi pengikatan data antara XML dan objek terlalu merepotkan (bagian lain adalah bahwa itu tidak terbiasa dengan XSLT dan butuh banyak waktu untuk mempelajarinya).
Saya selalu menggunakan pengikatan data XML yang disediakan oleh Delphi. Tentu saja, ini sangat nyaman setelah dihasilkan. Tetapi masalahnya adalah bahwa akan selalu ada beberapa perubahan selama proses pengembangan program. sangat merepotkan.
Jadi ketika saya memikirkan obyektifikasi set data, saya langsung berpikir bahwa saya juga dapat menggunakan RTTI untuk mengimplementasikan ketekunan XML objek - pada kenyataannya, implementasi SOAP dimulai dengan Delphi6 adalah dengan menggunakan RTTI untuk mengimplementasikan konversi objek ke data SOAP ( yaitu, xml). Jelas saya sudah sangat terlambat. Bekerja beberapa tahun yang lalu, dan saya segera memintanya untuk kode sumbernya. Lexlib adalah perpustakaan dengan banyak fungsi yang terlihat seperti perpustakaan kelas dasar .net (tentu saja tidak terlalu besar ^o ^). Karena saya hanya membutuhkan bagian ini, tidak perlu menggunakan seluruh perpustakaan ini begitu banyak masalah. menyelesaikan:
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 , tkset, tkwchar, tklstring, tkwstring, tkint64]; {tmxmlpersistent} prosedur kelas tmxmlpersistent.LoadObjFromxml; ; AOBJ adalah tmdataSetproxy) kemudian (aobj sebagai tmdatasetproxy) .loadFromXml (anode) mulai plist: = tmproplist.create (aobj); ; anode.childnodes [widestring (pinfo^.name)], tmpoBj sebagai tpersistent); Pinfo^.Name). Ppropinfo; Pinfo: = Plist.props [i]; if (pinfo^.proptype^.kind = tkclass) kemudian mulai tmpObj: = Tobject (integer (getPropValue (aobj, pinfo^.name))); (tmpObj adalah tpersistent)) kemudian saveObjtoxml (anode.addchild (widestring (pinfo^.name)), tmpObj as tpersistent); ^ .Name)) .teks: = getPropValue (aobj, pinfo^ .name)Implementasi ini harus dikatakan sangat sederhana. Terutama ada tiga bagian (struktur beban dan simpan serupa):
Pertama, pemrosesan khusus dilakukan untuk TMDatasetproxy dan mempercayakan kelas ini untuk menangani implementasinya sendiri. .
Yang kedua adalah untuk memproses kelas rekursif, dan tentu saja hanya mendukung kelas yang berasal dari tpersistent.
Ketiga, bidang umum dikonversi menjadi string dan disimpan, yang meminjam filter lexlib, dan hanya memproses tipe data yang dapat dengan mudah dikonversi menjadi string, memfilter jenis yang dapat menyebabkan kesalahan konversi.
Untuk TMPropList yang digunakan dalam kode di atas, lihat implementasi di "Menggunakan RTTI Delphi untuk mengimplementasikan set data".
Di bawah ini adalah ketekunan XML dari dataset yang diimplementasikan dengan TMDataSetProxy. Ini menghilangkan masalah menggunakan TClientDataSet, dan menggunakan metode perekaman bidang dengan node. Meskipun file XML yang dihasilkan dengan cara ini akan sedikit lebih besar, manfaatnya juga jelas, terutama XML yang saya rencanakan untuk digunakan dalam aplikasi web, dan direkam dalam node akan jauh lebih nyaman saat menggunakan XSLT.
Prosedur TMDataSetProxy.LoadFromXML (Anode: Ixmlnode); Var I, J: Integer; Childnodes [j]; untuk i: = 0 ke fproplist.propcount - 1 do pinfo: = fproplist.props [i]; [Pinfo^.Name). Teks)); Sementara foreach mulai Prow: anode.addChild ('Row'); untuk i: = 0 ke fproplist.propcount - 1 lakukan pinfo: = fproplist.props [i]; ) Kemudian Prow.AddChild (widestring (pinfo^.name)) .text: = getVariant (i);Di bawah ini adalah demo sederhana yang mencakup kegigihan XML dari dataset. Perhatikan bahwa ketika memuat, anggota karyawan terhubung ke Adodataset2, yang terhubung ke tabel yang berisi bidang -bidang ini. Setelah beban selesai, isi bidang ini dalam tabel karyawan akan disalin ke tabel ini.
TDemocompany = Tpersistent) Feminat swasta: TDSPEPLEYEE; TFORM1.SAVECLICK (Pengirim: TOBJEK); Demo Var: TDemocompany; ; Demo. Coba xmldocument1.active: true; Teks: = InttoStr (Demo.Code); Subitems.add (Demo.employee.lastname); . Gratis;
Akhirnya, saya bisa mengucapkan selamat tinggal pada ikatan data XML yang merepotkan, dan saya tidak perlu menulis XSD di masa depan - meskipun ada alat yang berguna, lebih baik menyimpan beberapa masalah.