작년에 나는 Delphi와 함께 XML 기반 웹 응용 프로그램을 개발하는 데 많은 시간을 보냈습니다. 초기 아이디어는 아름다웠지만 결과는 매우 간단하다는 것입니다. 그 이유 중 하나는 XML과 객체 사이의 데이터 바인딩 구현이 너무 번거 롭기 때문입니다 (다른 부분은 XSLT에 익숙하지 않아서 배우는 데 많은 시간이 걸리기 때문입니다).
Delphi가 제공하는 XML 데이터 바인딩을 항상 사용했습니다. 기본 방법은 XML 스키마 (XSD)를 사용하여 XML 데이터 바인딩을 사용하여 Delphi 인터페이스 및 클래스를 생성합니다. 물론 프로그램에서 생성되면 매우 편리합니다.이 인터페이스는 XSD로 정의됩니다. 그러나 문제는 프로그램의 개발 과정에서 항상 약간의 변화가있을 것이므로 XMLSPY를 열어서 동시에 XML 데이터 바인딩 마법사로 다시 실행해야합니다. 매우 번거 롭습니다.
따라서 데이터 세트의 객관화를 생각할 때 즉시 RTTI를 사용하여 XML 지속성의 객체를 구현할 수 있다고 생각합니다. 실제로 Delphi6으로 시작된 비누 구현은 RTTI를 사용하여 객체의 SOAP 데이터로의 변환을 구현하는 것입니다 ( 즉, XML)입니다. 분명히 나는 이미 매우 늦었다. "강력한 델파이 RTTI- 여러 개발 언어를 이해하는 데 필요한 파티 투 링크"에서 내 계획을 언급했을 때, 내 친구 Lex Chow는 그가 이것을 한 것에 대해 나에게 대답했다. 몇 년 전에 일을하면서 나는 즉시 그의 소스 코드를 요청했습니다. Lexlib는 많은 기능을 가진 라이브러리입니다. 이 부분 만 필요하기 때문에이 전체 라이브러리를 너무 많이 사용할 필요가 없으므로 Lexlib를 언급하고 "Delphi의 RTTI를 사용하여 간단한 데이터 세트를 사용하여 구현 한 부분과 결합했습니다. 성취하다:
tmxmlpersistent = class (tobject) 공개 클래스 절차로드 로브 Jfromxml (anode : ixmlnode; tpersistent); 잉 , tkwchar, tklstring, tkwstring, tkint64]; {tmxmlpersistent.loadobjfromxml; 시작 if 시작 aobj는 tmdatasetproxy입니다. if (pinfo^.proptype^.kind = tkclass)를 시작합니다. anode.childnodes [widestring (pinfo^.name)], tpersistent로 tmpobj; dele if (pinfo^.proptype^. pinfo^. ppropinfo; tmpobj : tobject; if (aobj는 tmdatasetproxy). pinfo : plist.props [i]; (tmpobj는 tpersistent)) 그런 다음 saveobjtoxml (anode.addchild (pinfo^.name), tmpobj as tpersistent); .이 구현은 매우 간단하다고 말해야합니다. 주로 세 부분이 있습니다 (하중 및 저장 구조는 비슷합니다) :
먼저, TMDATASETPROXY에 특별 처리가 이루어 지고이 클래스가 일반 클래스와 다르기 때문에 구현 자체를 처리하도록 맡기며, 이는 Foreach를 통해 모든 레코드를 통과해야합니다. .
두 번째는 클래스를 재귀 적으로 처리하는 것이며 물론 tpersistent에서 파생 된 수업 만 지원합니다.
셋째, 일반 필드는 단순히 문자열로 변환되어 LexLib의 필터를 빌리며 단순히 문자열로 변환 할 수있는 데이터 유형 만 처리하여 변환 오류를 유발할 수있는 유형을 필터링 할 수있는 데이터 유형 만 처리합니다.
위 코드에 사용 된 TMPROPLIST의 경우 "Delphi의 RTTI 사용을 사용하여 데이터 세트를 구현하는"구현을 참조하십시오.
아래는 tmdatasetproxy로 구현 된 데이터 세트의 XML 지속성입니다. tclientDataset을 사용하는 데 어려움이 없으며, .NET와 함께 필드를 녹화하는 방법도 사용합니다. 이러한 방식으로 생성 된 XML 파일은 약간 더 크지 만, 특히 웹 애플리케이션에서 사용하려는 XML은 XSLT를 사용할 때 노드에 기록 된 XML도 훨씬 편리합니다.
절차 tmdatasetproxy.loadfromxml (양성 : ixmlnode); ppropinfo; childnodes [j]; i : = 0 to fproplist.propcount -1 pinfo : = fproplist.props [i]; [pinfo^.name); foreach는 prow를 시작합니다 : = anode.addchild ( '행'); ) prow.addchild (pinfo^.name).
아래는 데이터 세트의 XML 지속성을 포함하는 간단한 데모입니다. 로드하면 직원이 ADODATASET2에 연결되며 각 필드 유형이 포함 된 테이블에 연결되어 있지만 컨텐츠는 비어 있고 EmployeeID의 ID가 제거됩니다. 로드가 완료되면 직원 테이블의 이러한 필드의 내용 이이 테이블에 복사됩니다.
tdemocompany (tpersistent) 프리플리어 : 문자열; tform1. var demo : tdemocompany.create; xmldocument 1. = true; demo.employee : nil; 끝; xmldocument1. = xmldocument1.loadfile (temp.xml); 텍스트 : inttostr (demo.code); subitems.Add (demo.employee.lastname) ( 'yyyy-mm-dd', demo.birthdate); . free; 끝;
마지막으로, 귀찮은 XML 데이터 바인딩에 작별 인사를 할 수 있으며 앞으로 XSD를 쓸 필요는 없습니다. 유용한 도구가 있지만 문제를 절약하는 것이 좋습니다.