ปีที่แล้วฉันใช้เวลามากในการพยายามพัฒนาเว็บแอปพลิเคชันที่ใช้ XML กับ Delphi ความคิดเริ่มต้นนั้นสวยงาม แต่ผลก็คือสิ่งที่ง่ายมาก ส่วนหนึ่งของเหตุผลคือการใช้งานการเชื่อมโยงข้อมูลระหว่าง XML และวัตถุนั้นลำบากเกินไป (ส่วนอื่น ๆ ก็คือไม่คุ้นเคยกับ XSLT และใช้เวลามากในการเรียนรู้)
ฉันใช้การเชื่อมโยงข้อมูล XML ที่จัดทำโดย Delphi แน่นอนว่ามันสะดวกมากเมื่อสร้างขึ้นในโปรแกรมฉันแค่ต้องใช้งานอินเทอร์เฟซนี้ แต่ปัญหาคือจะมีการเปลี่ยนแปลงบางอย่างในระหว่างกระบวนการพัฒนาของโปรแกรม ลำบากมาก
ดังนั้นเมื่อฉันนึกถึงการคัดค้านชุดข้อมูลฉันคิดว่าทันทีที่ฉันสามารถใช้ RTTI เพื่อใช้การคงอยู่ของ XML ของวัตถุ - อันที่จริงการใช้ SOAP เริ่มต้นด้วย Delphi6 คือการใช้ RTTI เพื่อใช้การแปลงวัตถุเป็นข้อมูล SOAP ( นั่นคือ XML) เห็นได้ชัดว่าฉันมาสายมากแล้ว ไม่กี่ปีที่ผ่านมาและฉันขอให้เขาใช้ซอร์สโค้ดของเขาทันที Lexlib เป็นไลบรารีที่มีฟังก์ชั่นมากมายที่ดูเหมือนไลบรารีคลาสพื้นฐานของ. Net (แน่นอนว่าไม่ใช่ Big ^O ^) เนื่องจากฉันต้องการเพียงส่วนนี้จึงไม่จำเป็นต้องใช้ห้องสมุดทั้งหมดนี้มาก ทำให้สำเร็จ:
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]; เริ่มต้นถ้า ( AOBJ คือ tmdatasetproxy) จากนั้น (aobj เป็น tmdatasetproxy) .loadfromxml (ขั้วบวก) อื่น ๆ เริ่มต้นขึ้น: = tmproplist.create (aobj); ถ้า (pinfo^.proptype^.kind = tkclass) จากนั้นเริ่มต้น tmpoBj: = tobject (จำนวนเต็ม (getPropvalue (aobj, pinfo^.name)); anode.childnodes [widestring (pinfo^.name)], tmpoBj เป็น tpersistent); pinfo^. name)]. ข้อความ); ppropinfo; pinfo: = plist.props [i]; ถ้า (pinfo^.proptype^.kind = tkclass) จากนั้นเริ่มต้น tmpoBj: = tobject (จำนวนเต็ม (getPropvalue (aobj, pinfo^.name))) (tmpoBj คือ tpersistent)) จากนั้น saveobjtoxml (anode.addchild (widestring (pinfo^.name)), tmpoBj เป็น tpersistent); ^ .NAME)). TEXT: = GetPropValue (AOBJ, PINFO^ .NAME)
การดำเนินการนี้ควรกล่าวว่าง่ายมาก ส่วนใหญ่มีสามส่วน (โครงสร้างของโหลดและบันทึกคล้ายกัน):
ขั้นแรกการประมวลผลพิเศษจะทำกับ TMDatasetProxy และมอบความไว้วางใจให้กับคลาสนี้เพื่อจัดการกับการใช้งานเอง .
ประการที่สองคือการประมวลผลคลาสซ้ำและแน่นอนว่ารองรับชั้นเรียนที่ได้จาก TPersistent เท่านั้น
ประการที่สามฟิลด์ทั่วไปจะถูกแปลงเป็นสตริงและบันทึกซึ่งยืมตัวกรองของ lexlib และประมวลผลเฉพาะประเภทข้อมูลที่สามารถแปลงเป็นสตริงการกรองประเภทเหล่านั้นที่อาจทำให้เกิดข้อผิดพลาดในการแปลง
สำหรับ TMProplist ที่ใช้ในรหัสข้างต้นดูการใช้งานใน "การใช้ RTTI ของ Delphi เพื่อใช้ชุดข้อมูล"
ด้านล่างคือการคงอยู่ของ XML ของชุดข้อมูลที่ใช้กับ TMDatasetProxy มันกำจัดปัญหาของการใช้ tclientDataset และใช้วิธีการบันทึกฟิลด์ด้วยโหนด แม้ว่าไฟล์ XML ที่สร้างขึ้นด้วยวิธีนี้จะมีขนาดใหญ่กว่าเล็กน้อย แต่ประโยชน์ก็ชัดเจนเช่นกันโดยเฉพาะ XML ที่ฉันวางแผนที่จะใช้ในเว็บแอปพลิเคชันและบันทึกในโหนดจะสะดวกกว่าเมื่อใช้ XSLT
ขั้นตอน tmdatasetproxy.loadfromxml (anode: ixmlnode); var i, j: จำนวนเต็ม; ChildNodes [J]; [PINFO^.NAME)]. ข้อความ); ในขณะที่ Foreach เริ่มต้น Prow: = anode.addchild ('row'); จากนั้น prow.addchild (Wildestring (pinfo^.name)) .Text: = getVariant (i);ด้านล่างเป็นตัวอย่างง่ายๆที่รวมถึงการคงอยู่ของ XML ของชุดข้อมูล โปรดทราบว่าเมื่อโหลดสมาชิกพนักงานเชื่อมต่อกับ Adodataset2 ซึ่งเชื่อมต่อกับตารางที่มีฟิลด์เหล่านี้ หลังจากโหลดเสร็จสิ้นเนื้อหาของฟิลด์เหล่านี้ในตารางพนักงานจะถูกคัดลอกไปยังตารางนี้
TDEMOCOMPANY = คลาส (TPERSISTENT) Private Femployee: TDSPEMPOLYEE; tform1.saveclick (ผู้ส่ง: tobject); Demo: Tdemocompany; ลองใช้ XMLDOCUMENT1.ACTION: = TRUE; demo.employee: = nil; demo.free; ลองใช้ XMLDOCUMENT1.ACTION: = TRUE; ข้อความ: = inttoStr (demo.code); subitems.add (demo.employee.lastname); . ฟรี;
ในที่สุดฉันสามารถกล่าวคำอำลากับการเชื่อมโยงข้อมูล XML ที่ลำบากและฉันไม่ต้องเขียน XSD ในอนาคต - แม้ว่าจะมีเครื่องมือที่มีประโยชน์ แต่ก็เป็นการดีกว่าที่จะบันทึกปัญหาบางอย่าง