データ バインド ウィザードによる XML ドキュメントの抽象化
XML ドキュメントで作業するには、TXMLDocument コンポーネントや、そのドキュメントにおいてノードとして現れる IXMLNode インターフェイスのみを使用して、もしくは、DOM インターフェイスのみとだけやり取りをして(TXMLDocument さえ使用せずに)、行うことができます。しかしながら、XML データ バインディング ウィザードを使用することにより、コードの記述ははるかにシンプルで、読みやすいものになるでしょう。
データ バインディング ウィザードは、XML スキーマやデータ ファイルを受け取り、その上のマッピングされるインターフェイスのセットを生成します。たとえば、次のような XML データがあるとします:
<customer id=1>
<name>Mark</name>
<phone>(831) 431-1000</phone>
</customer>
データ バインディング ウィザードは次のインターフェイスを生成します(それに伴い、それを実装するクラスも):
Delphi:
ICustomer = interface(IXMLNode)
['{8CD6A6E8-24FC-426F-9718-455F0C507C8E}']
{ Property Accessors }
function Get_Id: Integer;
function Get_Name: WideString;
function Get_Phone: WideString;
procedure Set_Id(Value: Integer);
procedure Set_Name(Value: WideString);
procedure Set_Phone(Value: WideString);
{ Methods & Properties }
property Id: Integer read Get_Id write Set_Id;
property Name: WideString read Get_Name write Set_Name;
property Phone: WideString read Get_Phone write Set_Phone;
end;
C++:
__interface INTERFACE_UUID("{F3729105-3DD0-1234-80e0-22A04FE7B451}") ICustomer :
public IXMLNode
{
public:
virtual int __fastcall Getid(void) = 0 ;
virtual DOMString __fastcall Getname(void) = 0 ;
virtual DOMString __fastcall Getphone(void) = 0 ;
virtual void __fastcall Setid(int Value)= 0 ;
virtual void __fastcall Setname(DOMString Value)= 0 ;
virtual void __fastcall Setphone(DOMString Value)= 0 ;
__property int id = {read=Getid, write=Setid};
__property DOMString name = {read=Getname, write=Setname};
__property DOMString phone = {read=Getphone, write=Setphone};
};
すべての子ノードが、プロパティにマッピングされますが、その際、プロパティ名は子ノードのタグ名と一致し、プロパティ値は子ノードのインターフェイス(子が内部ノードの場合)、もしくは、子ノードの値(末端ノードの場合)となります。すべてのノード属性もまたプロパティにマッピングされ、その際には、プロパティ名は属性名、プロパティ値は属性値となります。
XML ドキュメント内の各タグ付き要素に対するインターフェイス(および実装クラス)の作成に加え、ウィザードは、ルート ノードへのインターフェイスを取得するためのグローバル関数も作成します。たとえば、上記の XML は、ルート ノードにタグ <Customers>
があるドキュメントから生成されており、データ バインディング ウィザードは次のグローバル ルーチンを作成します:
Delphi:
function Getcustomers(Doc: IXMLDocument): IXMLCustomerType;
function Loadcustomers(const FileName: WideString): IXMLCustomerType;
function Newcustomers: IXMLCustomerType;
C++:
extern PACKAGE _di_ICustomers __fastcall GetCustomers(TXMLDocument *XMLDoc);
extern PACKAGE _di_ICustomers __fastcall GetCustomers(_di_IXMLDocument XMLDoc);
extern PACKAGE _di_ICustomers __fastcall LoadCustomers(const WideString FileName);
extern PACKAGE _di_ICustomers __fastcall NewCustomers(void);
Get... 関数は、TXMLDocument インスタンスのインターフェイスを取ります。Load... 関数は、動的に TXMLDocument インスタンスを作成し、インターフェイス ポインタを返す前に、指定された XML ファイルをその値として読み込みます。New... 関数は、新しい(空の) TXMLDocument インスタンスを作成し、ルート ノードへのインターフェイスを返します。
生成されたインターフェイスを使用すると、XML ドキュメントの構造をより直接反映しているため、コードが簡略化されます。たとえば、次のようなコードを記述する代わりに:
Delphi:
CustIntf := XMLDocument1.DocumentElement;
CustName := CustIntf.ChildNodes[0].ChildNodes['name'].Value;
C++:
_di_IXMLNode CustIntf = XMLDocument1->DocumentElement;
CustName = CustIntf->ChildNodes->Nodes->GetNode(0)->ChildNodes->Nodes[WideString("name")]->Value;
コードが次のようになります:
Delphi:
CustIntf := GetCustomers(XMLDocument1);
CustName := CustIntf[0].Name;
C++:
_di_ICustomers CustIntf = GetCustomers(XMLDocument1);
CustName = CustIntf->Nodes->GetNode(0)->Name;
データ バインディング ウィザードによって生成されたインターフェイスは、すべて IXMLNode を継承します。これはつまり、データ バインディング ウィザードを使用しないときと同じ方法で、子ノードを追加または削除できることを意味します(「XML ノードの操作」のセクション「子ノードの追加と削除」を参照)。さらに、子ノードが反復要素を表す場合(ノードのすべての子が同じタイプの場合)、親ノードにはさらに反復処理を追加するために、2 つのメソッド、Add、Insert が与えられます。これらのメソッドは、作成するノードのタイプを指定する必要がないため、AddChild を使用するよりシンプルです。
次のトピックでは、XML データ バインディング ウィザードの利用についての詳細情報を提供しています: