Google Apps ScriptのXmlServiceでXMLをparseする(或いはSalesforceにGASから接続する方法)

 

Google Apps Script(GAS)では、httpのPOSTやGETを行うことができます。

ということは、GASからSalesforceにログインして、データを取ってきて、GoogleSpreadSheetで表示することも出来そうだなーと思って、ログイン処理からコーディングし始めたのですが、思ったよりも手こずりました。

特に、ログイン後、返却されるXMLをパースしてログイン用のトークンを抽出するところが、難しかったです。

RSSやWebサービスの戻りの解析など、XML文書のパースはいたるところで使いそうですが、きちんとまとめておかないと、そのたびにつまづきそうなので、ここにメモっておきます。

 

UrlFetchAppを使って、ログインURLへデータをPOSTする

source

 

はじめに、UrlFetchApp.fetch()を使って、POSTを行います。

fetchの引数のoptionsにはヘッダやメソッド、実際のデータなどをセットします。

データには上記のようなXML文書を生成して、セットします。「username」と「password」は自分の環境に合わせて適宜変更してください。

 

XML文書から、XmlServiceを使ってparseし、文字列抽出する

さて、上記のようにloginし、成功すると、以下のようなXML文書が返ってきます。

このXMLから目的の文字列を抽出するのがひと苦労なんですよね。。

xml doc

 

今回は例として、データ取得の際にヘッダに埋め込むのが必要な「sessionId」を抽出してみたいと思います。

多分、他のXML文書で、なかなか目的の値を抽出できない人も同じように考えればOK かと。

キモは名前空間(NameSpace)です。

基本的には、

var xmlDoc = XmlService.parse(response.getContentText());
var rootDoc = xmlDoc.getRootElement();

でドキュメント全体の構造を取得したら、getChild() またはgetChildren()で目的の要素を抽出します。

このときに重要なのは、

  • Valid(妥当)なXML文書であること
  • Rootから順に要素をたどって目的の要素まを取得すること
  • 要素をgetChild() またはgetChildren()するときは、適切な名前空間(NameSpace)を引数に与えること

 

です。

順に確認していきましょう。

 

Valid(妥当)なXML文書であること

GoogleAppsScriptのXML文書パースでは、XML文書がValidであることが必要です。Validとは、DTDにきちんと基づいているということですね。

 

Rootから順に要素をたどって目的の要素まを取得すること

var entries = rootDoc.getChild('Body', nsSoapenv).getChild('loginResponse', nsDefault)

のように、Rootから順に要素をたどって目的の要素まで行きます。

その要素が1つの定義ならgetChild()、リスト形式で複数ならgetChildren()を使います。

 

要素をgetChild() またはgetChildren()するときは、適切な名前空間(NameSpace)を引数に与えること

上記のgetChild() には、第二引数で名前空間が渡されていることが分かります。

名前空間は、下の画像を例にすると、

の「soapenv」の部分です。では、soapenv名前空間の定義はどこにあるのかというと、XML文書の上の方を確認するとありますね。

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="urn:partner.soap.sforce.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

の部分です。

xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"

ですね。

つまり、に囲まれた部分をgetChild()するには、第二引数に

var nsSoapenv = XmlService.getNamespace("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");

のnsSoapenvを与える必要があります。

これを適切に与えないと、いくらやっても、getChild()/getChildren()の戻りが「null」になってしまいます。

以下のXML文書でいうと、それより下のタグには、名前空間がないですね。なので、デフォルトの(名前なし)の名前空間になります。

var entries = rootDoc.getChild('Body', nsSoapenv).getChild('loginResponse', nsDefault).getChild('result', nsDefault).getChild('sessionId', nsDefault);

上記のように、そこまで、順番にたどっていけばOKです。

いかがでしたでしょうか。

GoogleAppsScriptでのXML文書のパースは、結構頻出しますので、やり方を理解しておくと、いろいろなシーンに応用がきくと思いますよ。

ソースはこちら。

コメントを残す

サブコンテンツ

このページの先頭へ