今更ながらJavascriptでSOAPを通してxmlをparseする

![GETALLUSERS.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223443/a790aa51-79f7-faf1-9535-2ef00f5fc250.gif)

#やりたいこと
タイトルの通りで申し訳ないのですが、webserviceを呼び出そうとしたらRESTではなくSOAPだったんですね。。
RESTやJSONだと簡単にできてたところがなかなか難しかったりなので備忘録です。

##投げるところ
今回は[YellowfinのGETALLUSERS](http://wiki.yellowfinbi.jp/pages/viewpage.action?pageId=2294147)(クリックで技術仕様ページ)というサービスに投げます。SOAPでのリクエストやレスポンスが載っているのですが、基本的にはJavaでアクセスさせたいらしく、WSDLはあるもののJAVAのサンプル中心でどうしたらいいのかよくわからないです。

##前準備
ボタンとイベントリスナーを作るために、widgetからボタンを設置し、nameをGETALLUSERSにしときます。

##突然ですが全ソースです
見てもらえばわかると思うのですが、リクエストのXMLを文字列で構築して、XMLHttpRequestで投げているだけです。
リクエストが成功した時だけ、useridがある分アラートで表示している感じですね。

ここでのハマリポイントはparseの仕方だったのですが、基本的にはfind()でタグを取得して内容が1つならそのまま処理、複数ならeachで個別処理という流れになります。タグの要素名でも検索できるようなのですが、割愛します。

あとはヘッダーの設定をしっかりするということでしょうか。アプリケーションの設定かもしれないのですが、投げるのがテキストのxmlなのでContent-Typeにtext/xmlを設定して、SOAP通信であるというheaderのSOAPActionを設定しないと通信できませんでした(中身は空で大丈夫らしいです謎)


@htsign さんからのご指摘で簡略化することができました。ありがとうございます。

```javascript:JSタブ

    let button = this.apis.canvas.select('GETALLUSERS');
    button.addEventListener('click', () => {

        const xhr = new XMLHttpRequest();
        xhr.open('POST', 'http://localhost:8922/services/AdministrationService');
        var sr = '<?xml version="1.0" encoding="utf-8"?>' +
        '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://webservices.web.mi.hof.com/">' +
        '<soapenv:Header/>' +
        '<soapenv:Body>' +
        '<web:remoteAdministrationCall>' +
        '<arg0>' +
        '<loginId>admin@yellowfin.com.au</loginId>' +
        '<password>test</password>' +
        '<orgId>1</orgId>' +
        '<function>GETALLUSERS</function>' +
        '</arg0>' +
        '</web:remoteAdministrationCall>' +
        '</soapenv:Body>' +
        '</soapenv:Envelope>';
        xhr.responseType = 'document';
        xhr.onload = () => {
            xhr.response.querySelectorAll('multiRef').forEach(el => {
                const text = el.querySelector('userId')?.textContent;
                if (text) alert(text);
            });
        };
        // Send the POST request
        xhr.setRequestHeader('Content-Type', 'text/xml');
        xhr.setRequestHeader('SOAPAction', '');
        xhr.send(sr);

```

##ちなみに生responseXMLはこんな感じです
やっぱり見づらいですよね、RESTをくれ・・・。Yellowfin9.3ではadminサービスはRESTでほぼ網羅されるという話を聞いたのですがどうなんでしょうね。


```xml:response.xml

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soapenv:Body>
    <ns1:remoteAdministrationCallResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://webservices.web.mi.hof.com/">
      <remoteAdministrationCallReturn href="#id0" />
    </ns1:remoteAdministrationCallResponse>
    <multiRef id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns2:AdministrationServiceResponse" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns2="http://service.web.mi.hof.com">
      <binaryAttachments xsi:type="ns2:ArrayOfReportBinaryObject" xsi:nil="true" />
      <binaryData xsi:type="soapenc:string" xsi:nil="true" />
      <client xsi:type="ns2:AdministrationClientOrg" xsi:nil="true" />
      <clients xsi:type="ns2:ArrayOfAdministrationClientOrg" xsi:nil="true" />
      <contentResources xsi:type="ns2:ArrayOfContentResource" xsi:nil="true" />
      <contentType xsi:type="soapenc:string" xsi:nil="true" />
      <datasources xsi:type="ns2:ArrayOfAdministrationDataSource" xsi:nil="true" />
      <entityId xsi:type="soapenc:int" xsi:nil="true" />
      <errorCode href="#id1" />
      <fileName xsi:type="soapenc:string" xsi:nil="true" />
      <group xsi:type="ns2:AdministrationGroup" xsi:nil="true" />
      <groups xsi:type="ns2:ArrayOfAdministrationGroup" xsi:nil="true" />
      <importIssues xsi:type="ns2:ArrayOfImportIssue" xsi:nil="true" />
      <loadedDataSource xsi:type="ns2:AdministrationDataSource" xsi:nil="true" />
      <loginSessionId xsi:type="soapenc:string" xsi:nil="true" />
      <messages soapenc:arrayType="soapenc:string[2]" xsi:type="soapenc:Array">
        <messages xsi:type="soapenc:string">Successfully Authenticated User: admin@yellowfin.com.au</messages>
        <messages xsi:type="soapenc:string">Web Service Request Complete</messages>
      </messages>
      <parentDashboard xsi:type="ns2:ParentDashboard" xsi:nil="true" />
      <parentDashboards xsi:type="ns2:ArrayOfParentDashboard" xsi:nil="true" />
      <parentReportGroups xsi:type="soapenc:Array" xsi:nil="true" />
      <people soapenc:arrayType="ns2:AdministrationPerson[2]" xsi:type="soapenc:Array">
        <people href="#id2" />
        <people href="#id3" />
      </people>
      <person xsi:type="ns2:AdministrationPerson" xsi:nil="true" />
      <personfavourites xsi:type="ns2:ArrayOfPersonFavourite" xsi:nil="true" />
      <queryResults xsi:type="ns2:ArrayOfReportRow" xsi:nil="true" />
      <report xsi:type="ns2:AdministrationReport" xsi:nil="true" />
      <reportGroups xsi:type="ns2:ArrayOfAdministrationReportGroup" xsi:nil="true" />
      <reportId xsi:type="soapenc:int" xsi:nil="true" />
      <reports xsi:type="ns2:ArrayOfAdministrationReport" xsi:nil="true" />
      <roles xsi:type="ns2:ArrayOfAdministrationRole" xsi:nil="true" />
      <schedule xsi:nil="true" />
      <schedules xsi:type="ns3:ArrayOfAdministrationSchedule" xsi:nil="true" xmlns:ns3="http://schedule.service.web.mi.hof.com" />
      <sessionId xsi:type="soapenc:string">2967dba4dc0843a35428173d9acc390c</sessionId>
      <statusCode xsi:type="soapenc:string">SUCCESS</statusCode>
    </multiRef>
    <multiRef id="id3" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns4:AdministrationPerson" xmlns:ns4="http://service.web.mi.hof.com" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
      <emailAddress xsi:type="soapenc:string" xsi:nil="true" />
      <firstName xsi:type="soapenc:string">celery</firstName>
      <initial xsi:type="soapenc:string" xsi:nil="true" />
      <ipId href="#id4" />
      <languageCode xsi:type="soapenc:string" xsi:nil="true" />
      <lastName xsi:type="soapenc:string">test</lastName>
      <password xsi:type="soapenc:string" xsi:nil="true" />
      <roleCode xsi:type="soapenc:string">PUBLICCONTENTWRITERCOLLABORATORADVANCED</roleCode>
      <salutationCode xsi:type="soapenc:string" xsi:nil="true" />
      <status xsi:type="soapenc:string">ACTIVE</status>
      <timeZoneCode xsi:type="soapenc:string" xsi:nil="true" />
      <userId xsi:type="soapenc:string">admin2@yellowfin.com.au</userId>
    </multiRef>
    <multiRef id="id1" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="soapenc:int" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">0</multiRef>
    <multiRef id="id2" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns5:AdministrationPerson" xmlns:ns5="http://service.web.mi.hof.com" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
      <emailAddress xsi:type="soapenc:string" xsi:nil="true" />
      <firstName xsi:type="soapenc:string">System</firstName>
      <initial xsi:type="soapenc:string"></initial>
      <ipId href="#id5" />
      <languageCode xsi:type="soapenc:string" xsi:nil="true" />
      <lastName xsi:type="soapenc:string">Administrator</lastName>
      <password xsi:type="soapenc:string" xsi:nil="true" />
      <roleCode xsi:type="soapenc:string">YFADMIN</roleCode>
      <salutationCode xsi:type="soapenc:string" xsi:nil="true" />
      <status xsi:type="soapenc:string">ACTIVE</status>
      <timeZoneCode xsi:type="soapenc:string" xsi:nil="true" />
      <userId xsi:type="soapenc:string">admin@yellowfin.com.au</userId>
    </multiRef>
    <multiRef id="id4" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="soapenc:int" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">13150</multiRef>
    <multiRef id="id5" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="soapenc:int" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">5</multiRef>
  </soapenv:Body>
</soapenv:Envelope>

```

#本当は、
~~レポートのサービスでExcelファイルをバイナリで取得してJavascriptだけでファイルダウンロードしたかったのですが、どうしてもバイナリファイルが壊れてしまってExcelファイルが開けなかったのでこれは誰かやり方を教えて下さいﾟﾟ_(:3」∠)_
Base64エンコードされたバイナリファイルが落ちてくるんですがなんか壊れてるんですよね。Excelっぽい内容なのはわかるんですが。。~~
できたので別記事化したらリンクします。
できました→[Javascriptでbase64エンコード化されたExcelファイルをダウンロードする](https://qiita.com/celery/items/7a5952c9806630b4848b)

これで~~バイナリファイルの取り扱い以外の~~Webserviceのアクセスはできると思うので、JavaやPHPなんかで他にスクリプトくまなくてもある程度のことはできそうです。

##参考にさせていただきました
[jQuery ajaxでSOAP1.1する](https://qiita.com/logikuma/items/ae8c26b4a00013418711)
https://qiita.com/logikuma/items/ae8c26b4a00013418711

[jQuery.ajax(url[,settings])で、xml形式のデータを読み込みパースし表示](http://alphasis.info/2011/11/jquery-gyakubiki-jquery-ajax-url-xml/)
http://alphasis.info/2011/11/jquery-gyakubiki-jquery-ajax-url-xml/