Delphi Programming / Object Pascal
サイトのトップページへ リンクのページへ ロゴマーク
[掲載 2010年02月05日] [更新 2015年06月06日] Delphi サンプルプログラム集
   
921_WebAPI_REST による郵便番号と住所検索
動作確認等 Windows 7 U64  + Delphi XE Pro + Indy 10.5.7
本ページで使用している郵便番号検索 API は 2014年12月31日にサービス終了
921_WebAPI_REST_Postal.zip [4,624 KB] 2011年09月28日版 (EXE 同梱)



  • 2010年02月10日
  • [XMLのツリー表示2]を追加して,構成を変更
  • 2011年01月31日
  • [07]を追加
  • 2011年09月28日
  • リクエスト先の URL 変更に伴う修正




01_郵便番号から住所の情報を取得 ( 前方一致 )


[920_Web API XML-RPC 郵便番号] では,Web API を利用して郵便番号から住所を検索するテストをしました.それは XML-RPC 方式を用いました.このページのコードは現在多く使用されている REST 方式のサンプルプログラムです.
グローブテクノジーが提供している郵便番号検索 API を使用しています.REST は検索 API の URL にコマンドやパラメータの文字列を GET コマンド (Indy では GET メソッド) で送ります.リクエスト結果はいろいろな方式がありますが,ここでは XML で受取ります.XML は多くの Web API でサポートしています.
920 のサンプル同様,TXMLDocument (XMLDoc.pas) コンポーネントを使用して XML のデータバインディングをした pas ファイルを使用しています (プロジェクトに添付しています).

このサンプルプログラムの TEdit では,NumbersOnly プロパティの値を True にして,数値以外の入力を禁止していますが,この Web API では '-' があっても正常に検索してくれます.


[備考 1]
アクセスする Web API のアドレス (リクエスト URL) に付加するパラメータ (引数) の先頭は ? (クエスチョンマーク) です.2 番目以降のパラメータは,& (アンパサンド) でつなげます.各パラメータの値は = (イコール) で与えます.
パラメータに日本語がある場合は,エンコードが必要です.また,ファイル名等を使用する場合,パスの区切り文字に ¥ (円記号) は使用できません.DosPathToUnixPath 関数で変換しておきます.


[備考 2]
本ページで紹介している,グローブテクノジーの郵便番号検索 API サービスは,2014年12月31日に終了しています.したがって,本ページのサンプルを実行しても,郵便番号の検索はできません.
郵便番号検索 API 関係のサービスは他にもあります.ネット上で検索してみてください.



図1
設計時画面
  • TIdHTTP コンポーネント
    TXMLDocument コンポーネント
    を配置
  • TMemo に結果を表示
図2
完全一致検索の例
図3
前方 (先頭) 一致検索の例

リスト1
郵便番号 (前方一致) から住所の情報を検索
unit PostaToAddresUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, IdBaseComponent, IdComponent, IdTCPConnection,
  IdTCPClient, IdHTTP, ExtCtrls, xmldom, XMLIntf, msxmldom, XMLDoc;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Button1: TButton;
    IdHTTP1: TIdHTTP;
    XMLDocument1: TXMLDocument;
    Memo1: TMemo;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses ZipAddress;

{$R *.dfm}

//=============================================================================
//  郵便番号から住所の情報を取得(先頭一致)
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  ServiceURL : String;
  SeachStr   : String;
  GetStream  : TMemoryStream;
  AURL       : string;

  i          : Integer;
  AResultSet : IXMLGroovewebserviceType;
  Address    : IXMLAddressType;
  AOffice    : IXMLOfficeType;
  Str        : string;
begin
  if Edit1.Text = '' then begin
    ShowMessage('検索文字列が空です. ');
    exit;
  end;
  Memo1.Clear;

  Screen.Cursor := crHourGlass;

  GetStream := TMemoryStream.Create;
  try
    //リクエスト先のURL
    //以前のリクエスト先のURLは以下
    //http://groovetechnology.co.jp/ZipSearchService/v1/zipsearch
    ServiceURL := 'http://api.postalcode.jp/v1/zipsearch';
    //リクエスト内容のコマンドまたはパラメータの文字列
    SeachStr   := '?zipcode=' + Trim(Edit1.Text) +
                  '&format=xml';
    AURL       := ServiceURL + SeachStr;

    //GETで送信して結果をGetStremに取得する.リクエスト結果はXML
    try
      IdHTTP1.Get(AURL, GetStream);
    except
    end;

    //XMLをActiveにしてGetStreamからXMLに変換
    try
      XMLDocument1.Active := True;
      XMLDocument1.LoadFromStream(GetStream);
    except
    end;
  finally
    GetStream.Free;
  end;

  Memo1.Lines.BeginUpdate;

  //データセットへのアクセス
  AResultSet := Getgroovewebservice(XMLDocument1);

  if (AResultSet.Address.Count = 0) and (AResultSet.Office.Count = 0) then begin
    Memo1.Lines.Add('検索に失敗しました.');
  end else begin
    //まず事業所以外のリスト
    for i := 0 to AResultSet.Address.Count-1 do begin
      Address := AResultSet.Address[i];

      //表示用文字列を作成
      Str := Format('%7d ',  [Address.Zipcode]) +
             Address.Prefecture + ' ' +
             Address.City + ' ' +
             Address.Town;

      Memo1.Lines.Add(Str);
    end;

    //次に事業所のリスト
    //小字名,丁目,番地等と事業所名を追加
    for i := 0 to AResultSet.Office.Count-1 do begin
      AOffice := AResultSet.Office[i];

      //表示用文字列を作成
      Str := Format('%7d ',  [AOffice.Zipcode]) +
             AOffice.Prefecture + ' ' +
             AOffice.City + ' ' +
             AOffice.Town + ' ' +
             AOffice.Street + ' ' +
             AOffice.Office_name;

      Memo1.Lines.Add(Str);
    end;
  end;

  Memo1.Lines.EndUpdate;
  Screen.Cursor := crDefault;
  Edit1.SetFocus;
end;

end.




02_住所から郵便番号を検索 ( 前方一致 )


この Web API では,住所から郵便番号も検索できます.そのテストプログラムです.前方 (先頭) 一致検索ができます.前項のコードと違うところは,送信するコマンドだけです.TEdit は漢字も入力可能なように ImeMode を imHira にしています.
このサンプルでは,結果の表示の体裁はほとんど考慮していません.また住所等のカナも表示していません.必要であれば Web API の提供サイトで調べて追加してください.コード補完機能でも大方の予想はつくでしょう.


図4
設計時画面
  • TIdHTTP コンポーネント
    TXMLDocument コンポーネント
    を配置
  • TMemo は結果の表示用
図5
検索結果例1
図6
検索結果例2
  • [独立行政法人] の検索結果

リスト2
サンプルプログラムのコード
前項のサンプルと違うのはこのコードだけなので省略
    //リクエスト内容のコマンドまたはパラメータの文字列
    SeachStr   := '?word=' + HTTPEncode(Trim(Edit1.Text)) +
                  '&format=xml';




03_XML コードの整形


取得した XML は整形されていない場合があります.もちろん XML データバインディング作業に影響はありませんが,表示して確認したい場合は不便です,XMLDoc.pas 内の FormatXMLData 関数を使用すると簡単に整形できます.そのサンプルプログラムです.


図7
設計時画面
  • TXMLDocument コンポーネント
    TOpenDialog コンポーネント
    を配置
  • TMemo は確認用
図8
整形前
図9
整形後
  • 美人 (?) に変身

リスト3
XML コードの整形
unit XMLCodeFomatUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, xmldom, XMLIntf, msxmldom, XMLDoc;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Button1: TButton;
    Button2: TButton;
    XMLDocument1: TXMLDocument;
    OpenDialog1: TOpenDialog;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private 宣言 }
    BaseDir   : String;
    ADir      : String;
    AFileName : String;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//=============================================================================
//  [オリジナル]ボタン
//  整形前のXMLデータを読み込んで表示
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
begin
  if BaseDir = '' then BaseDir := ExtractFilePath(ParamStr(0));

  OpenDialog1.InitialDir := BaseDir;
  if OpenDialog1.Execute then begin
    ADir      := ExtractFilePath(OpenDialog1.FileName);
    AFileName := ExtractFileName(OpenDialog1.FileName);

    //XMLファイルを読み込む
    XMLDocument1.LoadFromFile(OpenDialog1.FileName);
    //表示
    Memo1.Text := XMLDocument1.XML.Text;
  end;
end;

//=============================================================================
//  [整形保存]
//  FormatXMLData関数で整形して保存
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
  StrXML : String;
begin
  if XMLDocument1.XML.Text = '' then begin
    ShowMessage('保存するXMLテキストがありません.');
    exit;
  end;

  //整形
  StrXML := XMLDoc.FormatXMLData(XMLDocument1.XML.Text);
  //確認表示
  Memo1.Text := StrXML;

  AFileName := ADir + 'Format' + AFileName;
  XMLDocument1.XML.Text := StrXML;
  //Activeにしないとエラー
  XMLDocument1.Active := True;
  XMLDocument1.SaveToFile(AFileName);
end;

end.




04_XML のツリー表示 1


XML をツリー表示するサンプルです.XML そのものを整形するのも一案ですが,ツリー表示すればその構造が明確になり,見通しが良くなる場合もあります.
各ノード (IXMLNode) の ChildNodes の数だけループし,NodeName と NodeText を表示します.


図10
設計時画面
  • TIdHTTP コンポーネント
    TXMLDocument コンポーネント
    TTreeView コンポーネント
    を配置
図11
取得結果

リスト4
XML のツリー表示 1
unit PostaToAddresXMLTree1Unit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, IdBaseComponent, IdComponent, IdTCPConnection,
  IdTCPClient, IdHTTP, ExtCtrls, xmldom, XMLIntf, msxmldom, XMLDoc;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Button1: TButton;
    IdHTTP1: TIdHTTP;
    XMLDocument1: TXMLDocument;
    Edit1: TEdit;
    TreeView1: TTreeView;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
    procedure BuildTree(TreeNode: TTreeNode; XMLNode: IXMLNode);
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//=============================================================================
//  郵便番号から住所の情報を取得(先頭一致)
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  ServiceURL : String;
  SeachStr   : String;
  GetStream  : TMemoryStream;
  AURL       : string;
begin
  if Edit1.Text = '' then begin
    ShowMessage('検索文字列が空です. ');
    exit;
  end;

  Screen.Cursor := crHourGlass;

  GetStream := TMemoryStream.Create;
  try
    //リクエスト先のURL
    //以前のリクエスト先のURLは以下
    //http://groovetechnology.co.jp/ZipSearchService/v1/zipsearch
    ServiceURL := 'http://api.postalcode.jp/v1/zipsearch';
    //リクエスト内容のコマンドまたはパラメータの文字列
    SeachStr   := '?zipcode=' + Trim(Edit1.Text) +
                  '&format=xml';
    AURL       := ServiceURL + SeachStr;

    //GETで送信して結果をGetStremに取得する.リクエスト結果はXML
    try
      IdHTTP1.Get(AURL, GetStream);
    except
    end;

    //XMLをActiveにしてGetStreamからXMLDocument1に代入
    //これでリクエスト結果のXMLが取得できたことになる
    try
      XMLDocument1.LoadFromStream(GetStream);
    except
    end;
  finally
    GetStream.Free;
  end;

  TreeView1.Items.Clear;
  TreeView1.Items.BeginUpdate;
  TreeView1.AutoExpand := True;

  //ノードのツリーを構成して表示
  BuildTree(nil, XMLDocument1.DocumentElement);

  TreeView1.Items.EndUpdate;
  Screen.Cursor := crDefault;
  Edit1.SetFocus;
end;

//=============================================================================
//  ツーリー構成用の関数
//=============================================================================
procedure TForm1.BuildTree(TreeNode: TTreeNode; XMLNode: IXMLNode);
var
  Node : TTreeNode;
  i    : Integer;
begin
  if  (XMLNode.NodeType = ntText) then  begin
    Node := TreeView1.Items.AddChild(TreeNode, XMLNode.NodeValue);
    //各ノードに対する操作はNodeプロパティに対して行う
    Node.SelectedIndex := 0;
  end else begin
    Node := TreeView1.Items.AddChild(TreeNode, XMLNode.NodeName);
    Node.SelectedIndex := 1;
  end;
  //子ノードの数だけこのBuildTreeを再帰的に呼出す
  for i :=  0 to  XMLNode.ChildNodes.Count - 1  do  begin
    BuildTree(Node, XMLNode.ChildNodes.Nodes[i]);
  end;
end;

end.




05_XML のツリー表示 2


XML をツリー表示するサンプルです.上のコードと少し表示スタイルを変更してみました.こちらの方がデータの把握がしやすいかも知れません.


図12
設計時画面
  • TIdHTTP コンポーネント
    TXMLDocument コンポーネント
    TTreeView コンポーネント
    を配置
図13
取得結果

リスト5
XML のツリー表示2
unit PostaToAddresXMLTree2Unit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, IdBaseComponent, IdComponent, IdTCPConnection,
  IdTCPClient, IdHTTP, ExtCtrls, xmldom, XMLIntf, msxmldom, XMLDoc;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Button1: TButton;
    IdHTTP1: TIdHTTP;
    XMLDocument1: TXMLDocument;
    Edit1: TEdit;
    TreeView1: TTreeView;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
    procedure BuildTree(TreeNode: TTreeNode; XMLNode: IXMLNode);
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//=============================================================================
//  郵便番号から住所の情報を取得(先頭一致)
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  ServiceURL : String;
  SeachStr   : String;
  GetStream  : TMemoryStream;
  AURL       : string;
begin
  if Edit1.Text = '' then begin
    ShowMessage('検索文字列が空です. ');
    exit;
  end;

  Screen.Cursor := crHourGlass;

  GetStream := TMemoryStream.Create;
  try
    //リクエスト先のURL
    //以前のリクエスト先のURLは以下
    //http://groovetechnology.co.jp/ZipSearchService/v1/zipsearch
    ServiceURL := 'http://api.postalcode.jp/v1/zipsearch';
    //リクエスト内容のコマンドまたはパラメータの文字列
    SeachStr   := '?zipcode=' + Trim(Edit1.Text) +
                  '&format=xml';
    AURL       := ServiceURL + SeachStr;

    //GETで送信して結果をGetStremに取得する.リクエスト結果はXML
    try
      IdHTTP1.Get(AURL, GetStream);
    except
    end;

    //XMLをActiveにしてGetStreamからXMLDocument1に代入
    //これでリクエスト結果のXMLが取得できたことになる
    try
      XMLDocument1.LoadFromStream(GetStream);
    except
    end;
  finally
    GetStream.Free;
  end;

  TreeView1.Items.Clear;
  TreeView1.Items.BeginUpdate;
  TreeView1.AutoExpand := True;

  //ノードのツリーを構成して表示
  BuildTree(nil, XMLDocument1.DocumentElement);

  TreeView1.Items.EndUpdate;
  Screen.Cursor := crDefault;
  Edit1.SetFocus;
end;

//=============================================================================
//  ツーリー構成用の関数
//=============================================================================
procedure TForm1.BuildTree(TreeNode: TTreeNode; XMLNode: IXMLNode);
var
  Node     : TTreeNode;
  NodeText : String;
  AttrNode : IXMLNode;
  i        : Integer;
begin
  //テキストノードや他の特殊な場合を除く
  if not (XMLNode.NodeType = ntElement) then exit;

   //ノード追加
   NodeText := XMLNode.NodeName;
   if XMLNode.IsTextElement then begin
     NodeText := NodeText + ' = '+ XMLNode.NodeValue;
   end;
   Node := TreeView1.Items.AddChild(TreeNode, NodeText);

   //属性があれば追加
   for i := 0 to XMLNode.AttributeNodes.Count-1 do begin
     AttrNode := XMLNode.AttributeNodes.Nodes[i];
     TreeView1.Items.AddChild(Node,
        '[' + AttrNode.NodeName + ' = "' + AttrNode.Text + '"]');
   end;

  //子ノードの数だけこのBuildTreeを再帰的に呼出す
  //一応子ノードの存在を確認してから
  if XMLNode.HasChildNodes then begin
    for i :=  0 to  XMLNode.ChildNodes.Count - 1  do  begin
      BuildTree(Node, XMLNode.ChildNodes.Nodes[i]);
    end;
  end;
end;

end.




06_XML データバインディングを使用しない方法


XML のデータバインディングをしないでも XML のデータは取得できます.それはノードツリーを調べて,値のあるノードから該当する値を取得する方法です.XML ドキュメント操作の基本を使用したやり方ということになります.実際には上のコードのように条件判断を入れといた方が確実です.


図14
設計時画面
  • TXMLDocument コンポーネント
    TMemo コンポーネント
    を配置
図15
データ取得結果例

リスト6
XML のノードを調査してデータを取得
unit PostaToAddresNonBindingUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, ExtCtrls, xmldom, XMLIntf, msxmldom, XMLDoc;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Button1: TButton;
    XMLDocument1: TXMLDocument;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//=============================================================================
//  XMLから住所情報を表示
//  XMLは前のサンプルプログラムで取得して保存したもの
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  RootNode : IXMLNode;
  ANode    : IXMLNode;
  i        : Integer;
  Str      : string;
begin
  Screen.Cursor := crHourGlass;

  //XMLファイルを読み込む
  XMLDocument1.LoadFromFile('ZipAddress.xml');

  Memo1.Clear;
  Memo1.Update;
  Memo1.Lines.BeginUpdate;

  //ルートノード
  RootNode := XMLDocument1.DocumentElement;

  for i := 0 to RootNode.ChildNodes.Count-1 do begin
    ANode := RootNode.ChildNodes[i];

    //ノード(タグ)名がaddressの場合
    if ANode.NodeName = 'address' then begin
      Str := ANode.ChildNodes['zipcode'].Text + ' ' +
             ANode.ChildNodes['prefecture'].Text +
             ANode.ChildNodes['city'].Text +
             ANode.ChildNodes['town'].Text;
      Memo1.Lines.Add(Str);
    end else
    //ノード(タグ)名がofficeの場合
    if ANode.NodeName = 'office' then begin
      Str := ANode.ChildNodes['zipcode'].Text + ' ' +
             ANode.ChildNodes['prefecture'].Text +
             ANode.ChildNodes['city'].Text +
             ANode.ChildNodes['town'].Text +
             ANode.ChildNodes['street'].Text + ' ' +
             ANode.ChildNodes['office_name'].Text;
      Memo1.Lines.Add(Str);
    end;
  end;

  Memo1.Lines.EndUpdate;
  Screen.Cursor := crDefault;
end;

end.




07_ XML マッパーを使用した方法 - DBGrid に表示


Enterprise 版以上であれば,XML Mapper (XML マッパー) という,XML マッピングツールがあります.実行ファイル名は xmlmapper.exe です.
これを利用すると,TClientDataSet,TXMLTransformProvider または TXMLTransform コンポーネントを使用して,取得した XML ファイルの内容を DBGrid に表示することができます.データバインド操作は必要ありません.
筆者が使用している Delphi は全て Pro 版なのですが,Delphi 6 Enterprise 版を使用する機会がありましたので,テストしてみました.

XML Mapper で変換ファイルを作成するには,データ構造の XML ファイルか実際のデータが格納されている XML ファイルが必要です,今回は,下のサンプルコード中の,XML ファイルを保存したところで,表示のコードは実行しないでプログラムを終了し,この保存した XML ファイルを使用しました.
XML Mapper ユーティリティ,xmlmapper.exe は該当 Delphi のバージョンがインストールされている環境でないと動作しません.Delphi 6 Enterprise 版がインストールされている Windows XP (SP3) で作成しています.


図16
xmlmapper.exe 起動
  • xmlmapper.exe がマッピングツール
図17 XML ファイルを開く
  • 本テストプログラムでは, Address.xml を開いて,
  • addres[*] でマウス右クリックのメニューから [すべての子ノードを選択] をクリック
リスト7 ノードリスト生成
  • 選択したノードのリストが作成される
図18 パケット作成
  • 同じく address[*] のメニューから [XMLからデータパケットを作成] をクリック
図19 データ表示確認
  • [変換の作成とテスト] ボタンをクリック
  • DBGrid が表示され,そこにデータが表示される
  • データがない XML から変換する場合は,当然表示されない
図20 変換を保存
  • [ファイル] から [変換] を選択して保存.本テストでは,デフォルトの名前 ToDp.xtr で保存した


これで準備ができました.郵便番号のサイトから XML データを取得して表示します.上の手順で作成した ToDp.xtr を,テストプロジェクトのフォルダ内に保存して使用しています.


図21
設計時画面
図22
データ取得結果例

リスト8
XML Mapper を使用て DBGrid に検索結果を表示
unit XMLMapperTestUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, IdBaseComponent, IdComponent, IdTCPConnection,
  IdTCPClient, IdHTTP, ExtCtrls, DB,
  DBClient, Grids, DBGrids, Provider, Xmlxform, DBCtrls, xmldom;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Button1: TButton;
    IdHTTP1: TIdHTTP;
    Edit1: TEdit;
    DBGrid1: TDBGrid;
    DataSource1: TDataSource;
    ClientDataSet1: TClientDataSet;
    XMLTransformProvider1: TXMLTransformProvider;
    procedure FormShow(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses HTTPApp;

{$R *.dfm}

//=============================================================================
//  テスト用に論策する住所をEdit1にセット
//=============================================================================
procedure TForm1.FormShow(Sender: TObject);
begin
  Edit1.Text := '東京都豊島区';
end;

//=============================================================================
//  住所から郵便番号を検索(先頭一致)
//
//  XMLデータの表示用に,以下のコンポーネント類を配置し,各プロパティを設定
//  あらかじめxmlmapper.exeを使用して,XMLマッピングファイル,ToDp.xtrを作成
//  xmlmapper.exeはEnterprise版以上に付属のXML Mapperユーティリティプログラム
//
//  DataSource1           : TDataSource;
//                          DataSet := ClientDataSet1;
//  ClientDataSet1        : TClientDataSet;
//                          ProviderName := XMLTransformProvider1;
//  XMLTransformProvider1 : TXMLTransformProvider;
//  DBGrid1               : TDBGrid;
//                          DataSource := DataSource1;
//
//  HTTPEncodeの使用には,usesにHTTPAppが必要
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  AddressStr : String;
  ServiceURL : String;
  SeachStr   : String;
  AURL       : String;
  GetStream  : TMemoryStream;
begin
  if Edit1.Text = '' then begin
    ShowMessage('検索文字列が空です. ');
    exit;
  end;

  Screen.Cursor := crHourGlass;
  GetStream     := TMemoryStream.Create;
  try
    //リクエスト先のURL
    //以前のリクエスト先のURLは以下
    //http://groovetechnology.co.jp/ZipSearchService/v1/zipsearch
    ServiceURL := 'http://api.postalcode.jp/v1/zipsearch';

    //リクエスト内容のコマンドまたはパラメータの文字列
    AddressStr := HTTPEncode(Trim(Edit1.Text));
    SeachStr   := '?word=' + AddressStr + '&format=xml';
    AURL       := ServiceURL + SeachStr;

    //GETで送信して結果をGetStremに取得する.リクエスト結果はXML
    try
      IdHTTP1.Get(AURL, GetStream);
      //取得したXMLをファイルに保存
      GetStream.SaveToFile('Address.xml');
    except
      Screen.Cursor := crDefault;
      ShowMessage('検索に失敗しました.');
      exit;
    end;
  finally
    GetStream.Free;
    Screen.Cursor := crDefault;
  end;

  //保存したXMLファイルを読み出してDBGridに表示
  ClientDataSet1.Active := False;
  XMLTransformProvider1.XMLDataFile := 'Address.xml';
  XMLTransformProvider1.TransformRead.TransformationFile := 'ToDp.xtr';
  ClientDataSet1.Active := True;

  //オンラインヘルプのTXMLTransformを使用した以下のコードでも表示可能
  //XMLTransform1.SourceXMLFile := 'Address.xml';
  //XMLTransform1.TransformationFile := 'ToDp.xtr';
  //ClientDataSet1.XMLData := XMLTransform1.Data;

  Edit1.SetFocus;
end;

end.