DataSpiderでXMLデータを可変的に受信する

DataSpiderでは、HTTPトリガーによってURLを設定することでHTTPクライアントからXMLデータでリクエストを送ることができます。

しかしXMLデータの整形時にマッピングコンポーネントだけを利用する場合、マッピングコンポーネント内にXMLの構造を指定してあげないとXML内部のデータを取得することができません。このように指定したマッピングコンポーネントでは指定した構造以外のXMLデータを取得することができません(バージョン4.2時点での情報です)。

マッピング内でXML構造を定義すると、それ以外の構造のXMLデータは扱うことができない。

今回、マッピングコンポーネントを利用することなく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を利用することで、リクエストデータの構造の変化にも対応したレスポンスデータを生成することができます。

『html_generate』コンポーネント内で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』にトリガーの入力データと出力データをそれぞれ設定するようにします。

『Request』,『Response』にそれぞれトリガーデータの入力データと出力データを設定

4.トリガーを実際に起動

トリガーの設定までできましたら、実際に起動させてみましょう。以下の画像はcurlを用いてPOSTリクエストしております。※PatternA.xmlはパターンAのXMLが、PatternB.xmlはパターンBのXMLが設定されております

実行結果(パターンA)
実行結果(パターンB)

『html_generate』コンポーネント内のテンプレートをDBやファイルで管理することも可能です。ほかにも様々な応用方法がありますので、ぜひ一度試してみてください。


<免責事項>
情報の掲載には注意を払っておりますが、掲載された情報の内容の正確性については一切保証しません。また、当サイトに掲載された情報を利用・使用(閲覧、投稿、外部での再利用など全てを含む)するなどの行為に関連して生じたあらゆる損害等につきましても、理由の如何に関わらず自己責任で行う必要があります。