API の呼び出し結果フォーマットはそれぞれ異なる
curl コマンドで様々なウェブ API を呼び出しますが、結果が XML で返ってくる場合 XML データが改行無しで表示されたりインデントが崩れていたりするため、綺麗に整形すると 非常に扱いやすく理解しやすくなります。実際、API 提供元によって XML のフォーマット(インデント幅等)が若干異なって いますので、その違いを吸収すると統一性がとれて非常に見やすくなります。
通常の curl コマンドで XML API を呼び出した場合
ここでは「JR 山手線 東京駅の情報」を取得する API と「郵便番号 103-0000 を現行郵便番号から検索し該当する住所を格納した XML 結果」を取得する API を呼び出してみます。まずは「JR 山手線 東京駅の情報」を取得する API を curl コマンドで呼び出してみます。
$ curl -sL http://www.ekidata.jp/api/s/1130224.xml <ekidata version="ekidata.jp station api 1.0"> <station> <pref_cd>13</pref_cd> <line_cd>11302</line_cd> <line_name>JR山手線</line_name> <station_cd>1130224</station_cd> <station_g_cd>1130101</station_g_cd> <station_name>東京</station_name> <lon>139.766103</lon> <lat>35.681391</lat> </station> </ekidata>
上記結果はインデント幅が8個のスペースになっています。
今度は「郵便番号 103-0000 を現行郵便番号から検索し該当する住所を格納した XML 結果を取得」という API を呼び出してみます。
$ curl -sL http://zip.cgis.biz/xml/zip.php?zn=1030000 <?xml version="1.0" encoding="utf-8" ?> <ZIP_result> <result name="ZipSearchXML" /> <result version="1.01" /> <result request_url="http%3A%2F%2Fzip.cgis.biz%2Fxml%2Fzip.php%3Fzn%3D1030000" /> <result request_zip_num="1030000" /> <result request_zip_version="none" /> <result result_code="1" /> <result result_zip_num="1030000" /> <result result_zip_version="0" /> <result result_values_count="1" /> <ADDRESS_value> <value state_kana="トウキョウト" /> <value city_kana="チュウオウク" /> <value address_kana="イカニケイサイガナイバアイ" /> <value company_kana="none" /> <value state="東京都" /> <value city="中央区" /> <value address="none" /> <value company="none" /> </ADDRESS_value> </ZIP_result>
こちらはインデントが全くありませんね。このように API 提供元によってフォーマット(インデント幅等)が異なります。また API によっては改行すら入っていない場合があり、整形し直す必要があります。
API からの XML 結果を整形する
では上記のようなフォーマットの違いをどうやって吸収すれば一番簡単でしょうか。それには xmllint というコマンドを使えば解決できます。
それでは先に呼び出した「JR 山手線 東京駅の情報」を取得する API を curl コマンドと xmllint コマンドを組み合わせて呼び出してみます。
$ curl -sL http://www.ekidata.jp/api/s/1130224.xml | xmllint --format - <?xml version="1.0" encoding="UTF-8"?> <ekidata version="ekidata.jp station api 1.0"> <station> <pref_cd>13</pref_cd> <line_cd>11302</line_cd> <line_name>JR山手線</line_name> <station_cd>1130224</station_cd> <station_g_cd>1130101</station_g_cd> <station_name>東京</station_name> <lon>139.766103</lon> <lat>35.681391</lat> </station> </ekidata>
上記結果はスペース2文字でインデントされています。
同様に、今度は「郵便番号 103-0000 を現行郵便番号から検索し該当する住所を格納した XML 結果を取得」という API を curl コマンドと xmllint コマンドを組み合わせて呼び出してみます。
$ curl -sL http://zip.cgis.biz/xml/zip.php?zn=1030000 | xmllint --format - <?xml version="1.0" encoding="utf-8"?> <ZIP_result> <result name="ZipSearchXML"/> <result version="1.01"/> <result request_url="http%3A%2F%2Fzip.cgis.biz%2Fxml%2Fzip.php%3Fzn%3D1030000"/> <result request_zip_num="1030000"/> <result request_zip_version="none"/> <result result_code="1"/> <result result_zip_num="1030000"/> <result result_zip_version="0"/> <result result_values_count="1"/> <ADDRESS_value> <value state_kana="トウキョウト"/> <value city_kana="チュウオウク"/> <value address_kana="イカニケイサイガナイバアイ"/> <value company_kana="none"/> <value state="東京都"/> <value city="中央区"/> <value address="none"/> <value company="none"/> </ADDRESS_value> </ZIP_result>
こちらも結果がスペース2文字でインデントされました。これでどの API を呼び出しても同じインデント幅で結果が得られます。
xmllint コマンドにはとても多くのオプションがありますので、それらを使うともっと柔軟なフォーマット変更が 可能です。またウェブ API だけでなく、様々な XML ファイルの変換にも利用できますので大変便利です。