L'année dernière, j'ai passé beaucoup de temps à essayer de développer une application Web basée sur XML avec Delphi. L'idée initiale était magnifique, mais le résultat a été que les choses étaient très simples. Une partie de la raison en est que la mise en œuvre de la liaison des données entre XML et l'objet est trop gênante (l'autre partie est qu'elle n'est pas familière avec XSLT et qu'il faut beaucoup de temps pour l'apprendre).
J'ai toujours utilisé la liaison des données XML fournie par Delphi. Bien sûr, il est très pratique une fois généré. Mais le problème est qu'il y aura toujours des changements pendant le processus de développement du programme. très gênant.
Ainsi, lorsque je pense à l'objectivation de l'ensemble de données, je pense immédiatement que je peux également utiliser RTTI pour implémenter la persistance XML de l'objet - en fait, l'implémentation de savon a commencé avec Delphi6 est d'utiliser RTTI pour implémenter la conversion de l'objet en données SOAP ( c'est-à-dire XML). Évidemment, j'étais déjà très tard. Travaillez il y a quelques années et je lui ai immédiatement demandé son code source. Lexlib est une bibliothèque avec de nombreuses fonctions qui ressemblent un peu à la bibliothèque de classe de base de .NET (bien sûr pas si grand ^ o ^). Parce que je n'ai besoin que de cette pièce, il n'est pas nécessaire d'utiliser cette bibliothèque entière tant de problèmes. accomplir:
TMXMLPERSISTENT = CLASSE (TOBject) Procédure de classe Public LoadoBJFromXML (Anode: IXMLNODE; AOBJ: TPERSISTENT); insigne , tkset, tkwchar, tklString, tkwstring, tkint64]; {tmxmlpersistent} procédure de classe tmxmlpersistent.loadoBjFromXml (anode: ixmlnode; commencer si ( AOBJ est tmdatasetproxy) alors (AOBJ comme tmdatasetproxy) .LoadFromXml (anode) Else Begin Plist: = tmproplist.create (aOBJ); ; anode.childNodes [welestring (pinfo ^ .name)], tmpoBj as tpersistent); Pinfo ^ .Name). Ppropinfo; tmpObj: tobject; begin if (aobj est tmdatasetproxy) alors (aobj as tmdatasetproxy) .savetoxml (anode) else begin plist: = tmproplist.create (aobj); pinfo: = Plist.props [i]; (tmpobj est tPeSistent)) puis SaveObJtOxMl (anode.addchild (welstring (pinfo ^ .name)), tmpobj as tpersistent); ^.Cette implémentation doit être considérée comme très simple. Il y a principalement trois parties (la structure de la charge et de la sauvegarde est similaire):
Premièrement, un traitement spécial est fait à TMDATASETPROXY et conteste cette classe pour gérer sa mise en œuvre elle-même. .
La seconde consiste à traiter de manière récursive la classe et, bien sûr, ne prend en charge que la classe dérivée de tPesistent.
Troisièmement, le champ général est simplement converti en chaîne et enregistré, qui emprunte le filtre de Lexlib, et ne traite que les types de données qui peuvent être simplement convertis en chaîne, filtrant ces types qui peuvent provoquer des erreurs de conversion.
Pour la TMProplist utilisée dans le code ci-dessus, consultez l'implémentation dans "Utilisation de RTTI de Delphi pour implémenter des ensembles de données".
Vous trouverez ci-dessous la persistance XML de l'ensemble de données implémenté avec TMDATASETPROXY. Il élimine les problèmes d'utilisation de TClientDataset et utilise la méthode d'enregistrement des champs avec le nœud. Bien que le fichier XML généré de cette manière sera légèrement plus grand, les avantages sont également évidents, en particulier le XML que je prévois d'utiliser dans les applications Web, et enregistré dans Node seront beaucoup plus pratiques lors de l'utilisation de XSLT.
Procédure tmdatasetproxy.loadFromXml (anode: ixmlnode); var i, j: entier; ChildNodes [J]; [Welsestring (finid; Tandis que ForEach commence à proue: = anode.addchild ('row'); ) Alors prow.AddChild (largestring (pinfo ^ .name)) .Text: = getVariant (i);Vous trouverez ci-dessous une simple démo qui comprend la persistance XML de l'ensemble de données. Notez que lors de la charge, le membre de l'employé est connecté à Adodataset2, qui est connecté à un tableau contenant ces champs. Une fois la charge terminée, le contenu de ces champs dans le tableau des employés sera copié dans ce tableau.
TDEMOCOMY = CLASSE (TPERSISTANT) FEMPLOYEZ PRIVÉE: TDSPELLAGE; Tform1.saveclick (expéditeur: tobject); Var Demo: TDEMOCOMY; ; Essayez XMLDocument1. Demo.Employee: = nil; Demo.Free; end; end; procédure tform1.loadClick (Sender: TOBject); Essayez xmlDocument1.cactif: = true; Texte: = inttoStr (Demo.Code); Subitems.Add (Demo.Employee.LaMe); .
Enfin, je peux dire au revoir à la liaison gênante des données XML, et je n'ai pas à écrire XSD à l'avenir - bien qu'il existe des outils utiles, il est préférable d'économiser des problèmes.