ハウツーガイド - XMLデータ形式
XMLデータ形式は、次のSDKメソッドを使用して指定できます:
| メソッド | 説明 |
|---|---|
request_format_xml | リクエスト本文をXML形式に変換する |
response_format_xml | レスポンス本文がXML形式であることを想定する |
format_xml | リクエストを変換し、レスポンス本文がXML形式であることを想定する |
リクエストでのXMLペイロードの形成
カスタムコネクタのアクションはRubyハッシュの形式でデータを受け取るため、フォーマットメソッドのいずれかをリクエストの末尾にチェーンして、これらのハッシュをXMLに変換する必要があります。 この例では、XMLデータ形式を使用してIntacct Webサービスにリクエストを行う方法について説明します。
Intacctドキュメントによると、すべてのリクエストはPOSTリクエストとして同じエンドポイントhttps://api.intacct.com/ia/xml/xmlgw.phtmlに対して行う必要があり、リクエストはXMLデータ形式であることが想定されています。
サンプルコードスニペット
<request>
<control>
<senderid>SENDER_ID</senderid>
<password>PASSWORD</password>
<controlid>testControlId</controlid>
<uniqueid>false</uniqueid>
<dtdversion>3.0</dtdversion>
</control>
<operation>
<authentication>
<login>
<userid>USER_ID</userid>
<companyid>COMPANY_ID</companyid>
<password>PASSWORD</password>
</login>
</authentication>
<content>
<function controlid="testControlId">
<inspect>
<object>USERINFO</object>
</inspect>
</function>
</content>
</operation>
</request>GLアカウント情報を取得するサンプルアクション、Get GL accountを次に示します。
get_GL_account: {
input_fields: lambda do
[
{
name: "key",
label: "Record ID",
optional: false
}
]
end,
execute: lambda do |connection, input|
response = post("https://api.intacct.com/ia/xml/xmlgw.phtml").
payload(
"control": [
{
"senderid": [{ "content!": connection["sender_id"] }],
"password": [{ "content!": connection["sender_password"] }],
"controlid": [{ "content!": "testControlId" }],
"uniqueid": [{ "content!": false }],
"dtdversion": [{ "content!": 3.0 }]
}
],
"operation": [
{
"authentication": [
{
"login": [
{
"userid": [{ "content!": connection["login_username"] }],
"companyid": [{ "content!": connection["company_id"] }],
"password": [{ "content!": connection["login_password"] }]
}
]
}
]
"content": [
{
"function": [
{
"@controlid": "testControlId",
"get_list": [
{
"@object": "glaccount",
"@maxitems": "1"
}
]
}
]
}
]
}
]).
headers("Content-type": "x-intacct-xml-request").
format_xml("request").
dig("response", 0,
"operation", 0,
"result", 0,
"data", 0,
"glaccount", 0) || {}
response.inject({}) do |hash (key, value)|
hash.merge(
{
key => value.dig(0, "content!")
})
end
end,
output_fields: lambda do |object_definitions|
object_definitions["budget"]
end
}かなり複雑です。 詳しく見ていきましょう。 まず、適切なエンドポイントにリクエストするPOSTを定義します:
post("https://api.intacct.com/ia/xml/xmlgw.phtml")次に、まずハッシュの形式でリクエストにペイロードを追加します:
.payload("control": [
{
"senderid": [{ "content!": connection["sender_id"] }],
"password": [{ "content!": connection["sender_password"] }],
"controlid": [{ "content!": "testControlId" }],
"uniqueid": [{ "content!": false }],
"dtdversion": [{ "content!": 3.0 }]
}
],
"operation": [
{
"authentication": [
{
"login": [
{
"userid": [{ "content!": connection["login_username"] }],
"companyid": [{ "content!": connection["company_id"] }],
"password": [{ "content!": connection["login_password"] }]
}
]
}
],
"content": [
{
"function": [
{
"@controlid": "testControlId",
"get_list": [
{
"@object": "glaccount",
"@maxitems": "1"
}
]
}
]
}
]
}
])XML要素は追加の表記なしで繰り返すことができるため、要素はハッシュの配列で表されます。 要素データはcontent!キーを使用して定義し、属性は@プレフィックスを使用して定義します(例: @objectおよび@maxitems)。
結果のXML本文は次のようになります:
<control>
<senderid>SENDER_ID</senderid>
<password>PASSWORD</password>
<controlid>testControlId</controlid>
<uniqueid>false</uniqueid>
<dtdversion>3.0</dtdversion>
</control>
<operation>
<authentication>
<login>
<userid>USER_ID</userid>
<companyid>COMPANY_ID</companyid>
<password>PASSWORD</password>
</login>
</authentication>
<content>
<function controlid="testControlId">
<get_list object="glaccount" maxitems="1"/>
</function>
</content>
</operation>XML要素の値の定義は、content!キーを使用して行います。 たとえば、<senderid>要素にパスワードを割り当てる場合、ハッシュは次のようになります:
{
"senderid": [{ "content!": connection["sender_id"] }]
}次に、複雑なXML要素はどのように形成すればよいでしょうか。 まず、1回だけ出現するXML要素(オブジェクト型)を形成してみましょう。 たとえば、リクエスト本文の<control>要素は、複数の要素がネストされた複合要素型です。 結果の部分XMLは次のようになります:
<control>
<senderid>SENDER_ID</senderid>
<password>PASSWORD</password>
<controlid>testControlId</controlid>
<uniqueid>false</uniqueid>
<dtdversion>3.0</dtdversion>
</control>これを形成するには、対応するハッシュでcontrolハッシュの直下にcontent!を定義しないようにします。 代わりに、<control>要素に属する各要素に対応するネストされたキーを含む、単一ハッシュの配列を定義します。
"control": [
{
"senderid": [{ "content!": connection["sender_id"] }],
"password": [{ "content!": connection["sender_password"] }],
"controlid": [{ "content!": "testControlId" }],
"uniqueid": [{ "content!": false }],
"dtdversion": [{ "content!": 3.0 }]
}
]<control>要素の直下にあるすべての要素がプリミティブ型であることに注意してください。 これらの各要素には値のみが含まれ、必要に応じて属性も含まれます。
これで、プリミティブXML要素の値を定義する方法がわかりました。 XML属性についてはどうでしょうか。 XML本文の<content>要素を見て、その方法を確認しましょう。
<content>
<function controlid="testControlId">
<get_list object="glaccount" maxitems="1"/>
</function>
</content>このXML要素には、2つの要素で定義された属性があります。 1つ目は複合要素<function>内にあり、プリミティブ要素<get_list>内にもあります。 このXMLを形成するための対応するハッシュ構造は次のようになります:
"content": [
{
"function": [
{
"@controlid": "testControlId",
"get_list": [
{
"@object": "glaccount",
"@maxitems": "1"
}
]
}
]
}
]複合XML要素内の属性とネストされた要素は同じ階層で定義しますが、属性を示すために@プレフィックスを使用します。 (<get_list>要素には"get_list"キー、controlid属性には"@controlid"キー)
同様に、プリミティブXML要素内の要素値と属性も同じ階層で定義されます。 (<get_list>要素の値には"content!"キー、object属性には"@object"キー) この例では、<get_list>要素に値は割り当てられていません。 値を割り当てる場合、対応するハッシュは次のようになります:
"content": [
{
"function": [
{
"@controlid": "testControlId",
"get_list": [
{
"@object": "glaccount",
"@maxitems": "1",
"content!": input["key"]
}
]
}
]
}
]これは次のXMLに変換されます:
<content>
<function controlid="testControlId">
<get_list object="glaccount" maxitems="1">KEY_VALUE<get_list>
</function>
</content>次に、headers短縮メソッドを使用して必要なヘッダーを追加します:
.headers("Content-type": "x-intacct-xml-request")最後に、format_xmlメソッドを使用し(リクエストとレスポンスの両方をXMLにする必要があるため)、ルート要素名<request>を引数として渡します。)
.format_xml("request")レスポンスからのXMLの処理
これで、同じリクエストからのレスポンスは次の形式になります:
<response>
<control>
<status>success</status>
<senderid>SENDER_ID</senderid>
<controlid>testControlId</controlid>
<uniqueid>false</uniqueid>
<dtdversion>3.0</dtdversion>
</control>
<operation>
<authentication>
<status>success</status>
<userid>USER_ID</userid>
<companyid>COMPANY_ID</companyid>
<sessiontimestamp>2017-03-26T05:24:25-07:00</sessiontimestamp>
</authentication>
<result>
<status>success</status>
<function>get_list</function>
<controlid>testControlId</controlid>
<listtype start="0" end="0" total="107">glaccount</listtype>
<data>
<glaccount>
<recordno>1</recordno>
<glaccountno>1000</glaccountno>
<title>Chase Operating Account</title>
<normalbalance>debit</normalbalance>
<accounttype>balancesheet</accounttype>
<closingtype>closed to account</closingtype>
<closingaccountno/>
<whenmodified>06/03/2016 20:19:30</whenmodified>
<status>active</status>
<requiredept>false</requiredept>
<requireloc>false</requireloc>
<taxable>false</taxable>
<taxcode/>
<mrccode/>
<alternativeaccount>None</alternativeaccount>
<requireproject>false</requireproject>
<requirecustomer>false</requirecustomer>
<requirevendor>false</requirevendor>
<requireemployee>false</requireemployee>
<requireitem>false</requireitem>
</glaccount>
</data>
</result>
</operation>
</response>リクエストでformat_xmlが呼び出されたため、Workato SDKは対応するハッシュを返します。 リクエストと同様に:
- XML要素は追加の表記なしで繰り返すことができるため、要素はハッシュの配列で表される
- 要素の属性には、ネストされた要素や要素値と同じ階層で
@がプレフィックスとして付加される - 要素値は
"content!"キーの値として渡される
{
"response"=>[
{
"control"=>[
{
"status"=>[{ "content!"=>"success" }],
"senderid"=>[{ "content!"=>"SENDER_ID" }],
"controlid"=>[{ "content!"=>"testControlId" }],
"uniqueid"=>[{ "content!"=>"false" }],
"dtdversion"=>[{ "content!"=>"3.0" }]
}
],
"operation"=>[
{
"authentication"=>[
{
"status"=>[{ "content!"=>"success" }],
"userid"=>[{ "content!"=>"USER_ID" }],
"companyid"=>[{ "content!"=>"COMPANY_ID" }],
"sessiontimestamp"=>[{ "content!"=>"2017-03-26T08:25:12-07:00" }]
}
],
"result"=>[
{
"status"=>[{ "content!"=>"success" }],
"function"=>[{ "content!"=>"get_list" }],
"controlid"=>[{ "content!"=>"testControlId" }],
"listtype"=>[
{
"@start"=>"0",
"@end"=>"0",
"@total"=>"107",
"content!"=>"glaccount"
}
],
"data"=>[
{
"glaccount"=>[
{
"recordno"=>[{ "content!"=>"1" }],
"glaccountno"=>[{ "content!"=>"1000" }],
"title"=>[{ "content!"=>"Chase Operating Account" }],
"normalbalance"=>[{ "content!"=>"debit" }],
"accounttype"=>[{ "content!"=>"balancesheet" }],
"closingtype"=>[{ "content!"=>"closed to account" }],
"closingaccountno"=>[{}],
"whenmodified"=>[{ "content!"=>"06/03/2016 20:19:30" }],
"status"=>[{ "content!"=>"active" }],
"requiredept"=>[{ "content!"=>"false" }],
"requireloc"=>[{ "content!"=>"false" }],
"taxable"=>[{ "content!"=>"false" }],
"taxcode"=>[{}],
"mrccode"=>[{}],
"alternativeaccount"=>[{ "content!"=>"None" }],
"requireproject"=>[{ "content!"=>"false" }],
"requirecustomer"=>[{ "content!"=>"false" }],
"requirevendor"=>[{ "content!"=>"false" }],
"requireemployee"=>[{ "content!"=>"false" }],
"requireitem"=>[{ "content!"=>"false" }]
}
]
}
]
}
]
}
]
}
]
}したがって、digメソッドを使用して目的のデータを抽出する必要があります。
.dig("response", 0,
"operation", 0,
"result", 0,
"data", 0,
"glaccount", 0)これにより、次のハッシュが返されます:
{
"recordno"=>[{ "content!"=>"1" }],
"glaccountno"=>[{ "content!"=>"1000" }],
"title"=>[{ "content!"=>"Chase Operating Account" }],
"normalbalance"=>[{ "content!"=>"debit" }],
"accounttype"=>[{ "content!"=>"balancesheet" }],
"closingtype"=>[{ "content!"=>"closed to account" }],
"closingaccountno"=>[{}],
"whenmodified"=>[{ "content!"=>"06/03/2016 20:19:30" }],
"status"=>[{ "content!"=>"active" }],
"requiredept"=>[{ "content!"=>"false" }],
"requireloc"=>[{ "content!"=>"false" }],
"taxable"=>[{ "content!"=>"false" }],
"taxcode"=>[{}],
"mrccode"=>[{}],
"alternativeaccount"=>[{ "content!"=>"None" }],
"requireproject"=>[{ "content!"=>"false" }],
"requirecustomer"=>[{ "content!"=>"false" }],
"requirevendor"=>[{ "content!"=>"false" }],
"requireemployee"=>[{ "content!"=>"false" }],
"requireitem"=>[{ "content!"=>"false" }]
}最後に、ここでハッシュをレシピで扱いやすい出力スキーマに戻します:
response.inject({}) do |hash, (key, value)|
hash.merge(
{
key => value.dig(0, "content!")
})
endこのアクションの出力は次のようになります:
{
"recordno": "1",
"glaccountno": "1000",
"title": "Chase Operating Account",
"normalbalance": "debit",
"accounttype": "balancesheet",
"closingtype": "closed to account",
"closingaccountno": null ,
"whenmodified": "06/03/2016 20:19:30",
"status": "active",
"requiredept": "false",
"requireloc": "false",
"taxable": "false",
"taxcode": null ,
"mrccode": null ,
"alternativeaccount": "None",
"requireproject": "false",
"requirecustomer": "false",
"requirevendor": "false",
"requireemployee": "false",
"requireitem": "false"
}アクションの実行例
リクエスト
POST https://api.intacct.com/ia/xml/xmlgw.phtml
Accept application/xml
Accept-Encoding gzip, deflate
Content-Type application/xml
Authorization Bearer
Content-type x-intacct-xml-requestリクエスト本文:
<request>
<control>
<senderid>SENDER_ID</senderid>
<password>PASSWORD</password>
<controlid>testControlId</controlid>
<uniqueid>false</uniqueid>
<dtdversion>3.0</dtdversion>
</control>
<operation>
<authentication>
<login>
<userid>USER_ID</userid>
<companyid>COMPANY_ID</companyid>
<password>PASSWORD</password>
</login>
</authentication>
<content>
<function controlid="testControlId">
<get_list object="glaccount" maxitems="1"></get_list>
</function>
</content>
</operation>
</request>レスポンス
ステータス: 200 OK
レスポンス本文:
<?xml version="1.0" encoding="UTF-8"?>
<response>
<control>
<status>success</status>
<senderid>SENDER_ID</senderid>
<controlid>testControlId</controlid>
<uniqueid>false</uniqueid>
<dtdversion>3.0</dtdversion>
</control>
<operation>
<authentication>
<status>success</status>
<userid>USER_ID</userid>
<companyid>COMPANY_ID</companyid>
<sessiontimestamp>2017-03-26T05:24:25-07:00</sessiontimestamp>
</authentication>
<result>
<status>success</status>
<function>get_list</function>
<controlid>testControlId</controlid>
<listtype start="0" end="0" total="107">glaccount</listtype>
<data>
<glaccount>
<recordno>1</recordno>
<glaccountno>1000</glaccountno>
<title>Chase Operating Account</title>
<normalbalance>debit</normalbalance>
<accounttype>balancesheet</accounttype>
<closingtype>closed to account</closingtype>
<closingaccountno/>
<whenmodified>06/03/2016 20:19:30</whenmodified>
<status>active</status>
<requiredept>false</requiredept>
<requireloc>false</requireloc>
<taxable>false</taxable>
<taxcode/>
<mrccode/>
<alternativeaccount>None</alternativeaccount>
<requireproject>false</requireproject>
<requirecustomer>false</requirecustomer>
<requirevendor>false</requirevendor>
<requireemployee>false</requireemployee>
<requireitem>false</requireitem>
</glaccount>
</data>
</result>
</operation>
</response>これは抽出され、次のように変換されます:
{
"recordno": "1",
"glaccountno": "1000",
"title": "Chase Operating Account",
"normalbalance": "debit",
"accounttype": "balancesheet",
"closingtype": "closed to account",
"closingaccountno": null ,
"whenmodified": "06/03/2016 20:19:30",
"status": "active",
"requiredept": "false",
"requireloc": "false",
"taxable": "false",
"taxcode": null ,
"mrccode": null ,
"alternativeaccount": "None",
"requireproject": "false",
"requirecustomer": "false",
"requirevendor": "false",
"requireemployee": "false",
"requireitem": "false"
}Last updated: