DataSpiderでXMLデータを可変的に受信する
DataSpiderでは、HTTPトリガーによってURLを設定することでHTTPクライアントからXMLデータでリクエストを送ることができます。
しかしXMLデータの整形時にマッピングコンポーネントだけを利用する場合、マッピングコンポーネント内にXMLの構造を指定してあげないとXML内部のデータを取得することができません。このように指定したマッピングコンポーネントでは指定した構造以外のXMLデータを取得することができません(バージョン4.2時点での情報です)。
今回、マッピングコンポーネントを利用することなくXMLデータを変換する方法を紹介します。この方法を利用することでリクエストで受け取るXMLデータの構造が複数個想定される場合であったとしても、1つのスクリプトで処理することが可能となります。
1.スクリプトの準備
今回、以下の2種のXMLデータがDataSpiderへ連携されることを前提とします。
パターンA
<root>
<ID>001</ID>
<Data>
<Input1>データ1</Input1>
<Input2>データ2</Input2>
<Input3>データ3</Input3>
</Data>
<LoopData>
<Content>繰り返し1</Content>
<Content>繰り返し2</Content>
<Content>繰り返し3</Content>
</LoopData>
</root>
パターンB
<root>
<ID>002</ID>
<Info>
<No1>データ1</No1>
<No2>データ2</No2>
<No3>データ3</No3>
</Info>
<ForData>
<Type>繰り返し1</Type>
<Type>繰り返し2</Type>
<Type>繰り返し3</Type>
</ForData>
</root>
パターンAとパターンBは要素名『ID』のタグ内の値によって識別されます(001の場合パターンA、002の場合パターンB)。最終的に以下のようなレスポンスXMLをクライアントに返すようなスクリプトを作成します。
<root>
<ID>001</ID>
<Result>OK</Result>
<InfoData>
<Output1>データ1</Output1>
<Output2>データ2</Output2>
<Output3>データ3</Output3>
</InfoData>
<ForLoop>
<LoopOutput>繰り返し1</LoopOutput>
<LoopOutput>繰り返し2</LoopOutput>
<LoopOutput>繰り返し3</LoopOutput>
</ForLoop>
<root>
2.スクリプトの作成
次に、以下のようなスクリプトを作成します。
このスクリプトには、スクリプト入力変数として『Request』(XML型)、スクリプト出力変数として『Response』(XML型)を用意しておきます。
スクリプト内のコンポーネントについて説明していきます。まず『html_generate』コンポーネントですが、これは『HTMLファイル生成』というコンポーネントを利用しております。このコンポーネントでは、内部でVelocityというテンプレートエンジンを利用できます。このVelocityを利用することで、リクエストデータの構造の変化にも対応したレスポンスデータを生成することができます。
ここで記載されているテンプレートの内容について、解説します。
#set($r = $start.Request)
これは、左辺($r)に対して右辺($start.Request)の内容を代入することを示しております。また、$start.Requestは受信したリクエストデータ『Request』を意味します。すなわち、この行では$rという値にリクエストデータを代入しこの後のテンプレートで利用しやすくする意味があります。
$r.getChild("ID").Text
$r.getChild("Data").getChild("Input1").Text
getChild(“XMLTag“).Textと記載することで、指定したXML要素のデータを取得・表示することができます。なお、getChildの後にさらにgetChildを記載することでより深い階層の要素を取得することができます。
#if($r.getChild("ID").Text == "001")
$r.getChild("Data").getChild("Input1").Text
#else
$r.getChild("Info").getChild("No1").Text
#end
#if(condition)…#else…#endとすることで、指定した条件分岐に沿った処理の分岐を行うことができます。この場合、ID要素内のデータが「001」と等しい場合$r.getChild(“Data”).getChild(“Input1”).Textを出力し、それ以外の場合$r.getChild(“Info”).getChild(“No1”).Textを出力します。
ちなみに今回は実装していませんが、#if(condition1)…#elseif(condition2)…#else…#endとすることで複数の条件分岐を行うことも可能です。
#foreach($LoopOutput in $r.getChild("LoopData").getChildren("Content"))
<LoopOutput>$LoopOutput.Text</LoopOutput>
#end
#foreach(obj in list)…#endとすることで、listの件数分処理を繰り返すことができます。この際、objにはそのループにおけるlistのデータが設定されます。また、getChildren(“XMLTag“)と記述することで、指定したXML要素のデータをlist形式で取得することができます。今回のケースでは、LoopData要素内のContentの数ぶん、<LoopOutput>$LoopOutput.Text</LoopOutput>を出力します。また、$LoopOutput.Textには、Contentの要素値が設定されることになります。
ここまでで作成したXMLデータを指定したファイルに出力します。そのファイルのデータを「XMLファイル読み取り」コンポーネント『xml_read』にて読み込んで『Response』に設定します。
3.トリガーの実装
作成したスクリプトを起動するためのトリガーを設定します。まずは前述のスクリプトをサービス登録しましょう。
サービスを登録したら、HTTPトリガーでそのサービスを起動するように設定します。なおこの際、スクリプト変数の『Request』と『Response』にトリガーの入力データと出力データをそれぞれ設定するようにします。
4.トリガーを実際に起動
トリガーの設定までできましたら、実際に起動させてみましょう。以下の画像はcurlを用いてPOSTリクエストしております。※PatternA.xmlはパターンAのXMLが、PatternB.xmlはパターンBのXMLが設定されております
『html_generate』コンポーネント内のテンプレートをDBやファイルで管理することも可能です。ほかにも様々な応用方法がありますので、ぜひ一度試してみてください。
<免責事項>
情報の掲載には注意を払っておりますが、掲載された情報の内容の正確性については一切保証しません。また、当サイトに掲載された情報を利用・使用(閲覧、投稿、外部での再利用など全てを含む)するなどの行為に関連して生じたあらゆる損害等につきましても、理由の如何に関わらず自己責任で行う必要があります。