この文書は、W3Cノート Simple Object Access Protocol (SOAP) 1.1の翻訳である。正式な版は、W3Cのサイトにある英語版であってこの翻訳ではない。この翻訳は原文と技術的に等価なことを意図しているが、翻訳上の誤りはあり得る。
Copyright© 2000 DevelopMentor, International Business Machines Corporation, Lotus Development Corporation, Microsoft, UserLand Software
SOAPは非集中、分散環境における情報交換のための軽量のプロトコルである。SOAPはXMLベースのプロトコルであり3つの部分で構成されている。メッセージの中に何があってそれをどう処理するのかということを記述するためのフレームワークを定義したエンベロープ、アプリケーションが定義したデータ型のインスタンスを表現するための符号化規則の集合、RPC(Remote Procedure Call)とそれへのレスポンスを表現するための規約、の3つである。SOAPは潜在的には他のさまざまなプロトコルとの組合わせで利用することができるが、この文書ではSOAPをHTTPとHTTP拡張フレームワークとの組合わせで使うためのバインディングのみを定義する。
この文書はWorld Wide Web Consortiumへの投稿(Submission Request、W3C Staff Commentを参照)であり、XMLベースのプロトコルの領域に関するワーキンググループの形成を提案するものである。著者へのコメントは歓迎するが、考察や検討をW3Cの公開のメーリングリスト<xml-dist-app@w3.org>で共有することを奨励している( アーカイブを参照)。
この文書はW3Cから入手できるNOTEであり議論のためのみのものである。W3Cによるこのノートの公開はW3C、W3Cのチーム、あるいはW3C会員の支持を意味するものではない。このノートの準備にあたってW3Cはなんの編集上の統制も行っていない。この文書は作業中のものであり、任意の時点で他の文書によって更新、置換え、時代遅れなものにされてしまうかもしれない。
現在のW3Cの技術文書のリストはTechnical Reports pageで見ることができる。
SOAPは非集中/分散環境におけるシステム間の構造化され型付けされた情報の交換のためのXMLを用いた単純で軽量なメカニズムを提供する。SOAP自体はプログラミングモデルや実装固有の意味といったいかなるアプリケーションのセマンティックスも定義しない。SOAPは、データをモジュールとして符号化するためのモジュール式のパッケージングモデルと符号化のメカニズムを提供することにより、アプリケーションのセマンティクスを表現するための単純なメカニズムを定義する。これによってメッセージングシステムからRPCまで非常に広範囲にわたるシステムでSOAPを活用することができる。
SOAPは3つの部分から成る:
これらの部分はSOAPの一部として一緒に記述されているが、機能的には直交している。特にエンベロープと符号化規則は別々の名前空間(namespace)内で定義されておりモジュール化による単純さを実現している。
本仕様では、SOAPエンベロープ、SOAP符号化規則そしてSOAP RPC規約に加えて、2つのプロトコルバインディングを定義しており、それらはSOAPメッセージがどのようにしてHTTP[5]メッセージとして搬送されるのかを、HTTP拡張フレームワーク[6]を用いる場合と用いない場合の両方について記述している。
SOAPの主要な設計目標は単純さと拡張性である。これは伝統的なメッセージングシステムや分散オブジェクトシステムの持つ特徴でSOAP仕様の中核には含まれないものがあることを意味する。そのような特徴としては以下のようなものがある。
文書中のキーワード "MUST(しなけらばならない)", "MUST NOT(してはならない)", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD(すべきである)", "SHOULD NOT", "RECOMMENDED", "MAY(してもよい)", 及び "OPTIONAL" はRFC-2119 [2]の記述に従って解釈される。
本文書内で使われている名前空間の接頭辞(prefix) "SOAP-ENV"と"SOAP-ENC"はSOAPの名前空間 "http://schemas.xmlsoap.org/soap/envelope/"と"http://schemas.xmlsoap.org/soap/encoding/"にそれぞれ関連付けられている。
文書全体を通して、名前空間接頭辞"xsi"は[10]で定義されているURI "http://www.w3.org/1999/XMLSchema-instance"に関連付けられていると仮定する。名前空間接頭辞"tns"は現行の文書の対象名前空間を示すのに使われる。他のすべての名前空間接頭辞は説明用のサンプルである。
一般に"some-URI"という形式の名前空間URIはいくつかのアプリケーション依存または文脈依存のURI[4]を表わす。
この仕様ではある種の構造を表現するためにRFC-2616 [5]に記述されている拡張Backus-Naur形式(BNF)を用いる。
この例では、SOAPリクエストGetLastTradePriceがStockQuoteサービスに送られる。このリクエストは株の銘柄指定用の記号を示す文字列パラメータを持っており、SOAPレスポンスでは浮動小数点の値が返される。SOAP Envelope要素がSOAPメッセージを表現するXML文書の最上位の要素である。SOAP固有の識別子とアプリケーション固有の識別子を明確に区別するためにXML名前空間が使われている。この例は6節で定義されているHTTPとのバインディングを示している。 SOAP中のペイロード部分のXMLフォーマットを決める規則とペイロードがHTTPによって運ばれるという事実とが、完全に独立であることに特に意義がある。
さらに多くの例を付属書Aで見ることができる。
例1 HTTPリクエスト中に埋め込まれたSOAPメッセージ
POST /StockQuote HTTP/1.1
Host: www.stockquoteserver.com
Content-Type: text/xml; charset="utf-8"
Content-Length: nnnn
SOAPAction: "Some-URI"
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<m:GetLastTradePrice xmlns:m="Some-URI">
<symbol>DIS</symbol>
</m:GetLastTradePrice>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
SOAPメッセージをペイロードとして持ったHTTPメッセージを含むレスポンスメッセージを以下に示す。
例2 HTTPレスポンス中に埋め込まれたSOAPメッセージ
HTTP/1.1 200 OK
Content-Type: text/xml; charset="utf-8"
Content-Length: nnnn
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
<SOAP-ENV:Body>
<m:GetLastTradePriceResponse xmlns:m="Some-URI">
<Price>34.5</Price>
</m:GetLastTradePriceResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
SOAPのメッセージは基本的には送信者から受信者への一方通行で伝達される。しかし、前の例のようにリクエスト/レスポンスのようなパターンを実現するためにSOAPメッセージを組み合わせて使うことがしばしばある。
特定のネットワークシステムの特徴を活かすようにSOAPの実装を最適化することができる。例えば、6節に記述されているHTTPバインディングではSOAPのレスポンスメッセージを元になったリクエストと同じコネクションを使ってHTTPのレスポンスとして配信する。
SOAPがどんなプロトコルと結びついているかにかかわらず、メッセージはいわゆる"メッセージパス(message path)"に沿って送られていく。メッセージは最終的な送付先に加えてメッセージパス上の複数の中間的ノードで処理されてもよい。
SOAPメッセージを受信するSOAPアプリケーションは以下のアクションを以下の順に実行することによりメッセージを処理しなければならない。
SOAPのプロセッサはメッセージまたはメッセージの一部を処理するために、正しい処理に必要な他のセマンティックスだけでなく、とりわけ、情報交換のパターン(一方通行、リクエスト/レスポンス、マルチキャストなど)、そのパターンにおける受信者(recipient、訳注:以降の文脈でこの単語はメッセージの最終送付先だけでなく仲介者に対しても使われている)の役割、(もしあれば)7節に文書化されているようなRPCメカニズムの利用、データの表現または符号化について理解している必要がある。
SOAPのencodingStyle属性(4.1.1節を参照)のような属性をメッセージのある種の様相を記述するために使うことができるものの、一般にはこの仕様は受信者がその種の判定を行うための特定の手法を強制するものではない。例えば、あるアプリケーションは特定の<getStockPrice>要素が7節の規約に基づいてRPCリクエストを伝えている、ということを理解するだろう。一方、別のアプリケーションはすべての自分宛のデータは一方通行のメッセージとして符号化されていると結論づけるかもしれない。
すべてのSOAPメッセージはXML(XMLについての詳細は[7]を参照)を用いて符号化される。
SOAPアプリケーションは生成したメッセージ中のSOAPで定義されているすべての要素と属性について正しいSOAP名前空間を埋め込むべきである。SOAPアプリケーションは受け取ったメッセージ中のSOAP名前空間を処理できなければならない。アプリケーションは間違った名前空間を持ったメッセージを破棄しなければならない(4.4節を参照)。また、アプリケーションは名前空間の指定のないメッセージを正しいSOAP名前空間が指定されているかのように処理してもよい。
SOAPは2つの名前空間(XML名前空間の詳細については[8]を参照)を定義する。
SOAPメッセージは文書型宣言を含んではならない。 SOAPメッセージは処理命令を含んではならない。[7]
SOAPは、ID型のローカルで修飾されないid属性を用いて、符号化された要素の一意な識別子を指定する。SOAPは、XML仕様 [7]、XMLスキーマ仕様 [11]、そしてXML Linking Language仕様[9]に従った手法により、"uri-reference"型のローカルで修飾されない属性"href"を用いて、その値への参照を指定する。
SOAPのmustUnderstand属性(4.2.3節を参照)とactor属性(4.2.2節を参照)を除いて、一般には属性とその値をXMLインスタンスまたはその代替としてスキーマ中に出現させて同じ効果をもたらすようにして差し支えない。すなわち、DTDまたはスキーマ中にデフォルトまたは固定の値とともに宣言された属性はインスタンス中に出現した属性と意味的に等価である。
SOAPメッセージとは必須のSOAPエンベロープ、任意のSOAPヘッダ、必須のSOAP本体から構成されたXML文書である。本仕様の以降の部分ではこのようなXML文書をSOAPメッセージとして参照する。本節で定義される要素や属性のための名前空間識別子は"http://schemas.xmlsoap.org/soap/envelope/"である。SOAPメッセージは以下のようなものを含む。
構文は以下のとおりである:
SOAP encodingStyleグローバル属性はSOAPメッセージ中で使われる直列化の規則を示すのに使うことができる。この属性は任意の要素に対して現われてもよい。その適用範囲は(XML名前空間宣言と同様に)encodingStyle属性を含む要素そのものではなく、その要素の内容とすべての子要素である。SOAPメッセージに対してデフォルトで定義されている符号化方式はない。
属性の値は、直列化の規則または直列化されたSOAPメッセージを元にもどす規則を識別する一つかそれ以上のURIの順序付きリストである。特定の修飾されたものからより一般的なものへ、という順番である。属性値の例を次に示す。
"http://schemas.xmlsoap.org/soap/encoding/"
"http://my.host/encoding/restricted http://my.host/encoding/"
""
5節中で定義されているSOAPの直列化規則はURI "http://schemas.xmlsoap.org/soap/encoding/"によって識別される。この特定の直列化の方式を使用するメッセージはそのことをencodingStyle属性を用いて示すべきである。さらにURIの構文が"http://schemas.xmlsoap.org/soap/encoding/"で始まるURIは5節で定義されている符号化規則(今後より厳密な規則が追加される可能性はあるが)と適合することを示す。
長さ0のURI ("")の値は含まれている要素の符号化方式(encoding style)に関して何の指定もないことを明示的に示す。これはその要素の上位要素からの符号化方式に関する指定を無効にするために使うことができる。
SOAPではメジャーバージョン番号とマイナーバージョン番号に基づく伝統的なバージョニングモデルを定義していない。SOAPメッセージは"http://schemas.xmlsoap.org/soap/envelope/"名前空間と関連付けられたEnvelope要素を含まなければならない。もしSOAPアプリケーションが、Envelope要素が異なる名前空間に関連付けられているメッセージを受け取ったなら、アプリケーションはそのメッセージをバージョンエラーとして扱いそのメッセージを破棄しなければならない。そのメッセージがHTTPのようなリクエスト/レスポンスプロトコルにより受信された場合には、アプリケーションはSOAP "http://schemas.xmlsoap.org/soap/envelope/"名前空間を使ってSOAP VersionMismatch faultcodeメッセージ(4.4節を参照)を返さなくてはならない。
SOAPは通信の当事者間が事前知識無しで非集中でモジュール化された方式でメッセージを拡張する柔軟なメカニズムを提供する。ヘッダ項目(header entry)として実現可能なそのような拡張の例としては、認証やトランザクション管理、支払いなどがある。
Header要素はSOAPのEnvelope要素の最初の子要素として符号化される。Header要素のすべての子要素はヘッダ項目と呼ばれる。
ヘッダ項目のための符号化規則を以下に示す。
本節で定義されているSOAPヘッダ属性はSOAPメッセージの受信者が2節で記述されているようなメッセージをどのようにして処理すべきかを決定する。SOAPメッセージを生成するSOAPアプリケーションはSOAP Header要素の子要素に対してのみSOAP ヘッダ属性を使用するべきである。SOAPメッセージの受信者はSOAP Header要素の子要素以外に適用されているSOAPヘッダ属性を無視しなければならない。
要素名"Transaction"、"mustUnderstand"属性の値が1、要素の値が5という例は以下のように符号化される。
<SOAP-ENV:Header>
<t:Transaction
xmlns:t="some-URI" SOAP-ENV:mustUnderstand="1">
5
</t:Transaction>
</SOAP-ENV:Header>
SOAPメッセージはメッセージパスに沿って一連のSOAP仲介者(intermediary)を経て作成者から最終的な送付先まで送られるかもしれない。SOAP仲介者とはSOAPメッセージを受け取りかつ転送できるアプリケーションである。仲介者も最終送付先と同様にURIによって識別される。
SOAPメッセージのすべての部分が最終送付先向けに用意されているわけではなく、一部はメッセージパス上の一つかそれ以上の仲介者向けに用意されているものかもしれない。ヘッダ項目要素の受信者の役割は他に開示してはいけない契約書を受けとった場合の役割に似ている。すなわち、ヘッダ項目要素の受信者はそのヘッダ項目要素をメッセージパス上の次のアプリケーションに転送してはいけない。受信者は類似のヘッダ項目要素を挿入してもよい。しかし、その場合その契約は挿入を行ったアプリケーションとそのヘッダ項目要素の受信者との間の取り決めとなる。
SOAPのactorグローバル属性をヘッダ項目要素の受信者を示すために使うことができる。SOAPのactor属性の値はURIである。特別なURI "http://schemas.xmlsoap.org/soap/actor/next"はそのヘッダ項目がメッセージを処理する一番最初のアプリケーション用に用意されたものであることを示す。これはHTTPのConnectionヘッダフィールドで表現されるhop-by-hop scope modelに類似している。
SOAPのactor属性を省略することは(訳注:ヘッダ項目の)受信者がSOAPメッセージの最終送付先であることを示す。
この属性が有効であるためにはSOAPのメッセージのインスタンス中に現れなければならない(3節と4.2.1節を参照)。
SOAPのmustUnderstandグローバル属性を受信者がヘッダ項目を必ず処理しなければならないのか、あるいは、選択可能かということを示すのに使うことができる。ヘッダ項目の受信者はSOAPのactor属性(4.2.2節を参照)によって定義される。mustUnderstand属性の値は"1"または"0"である。mustUnderstand属性が無ければ値が"0"の属性があるのと同じ意味である。
ヘッダ項目要素が値"1"のmustUnderstand属性とともにタグ付けされているとき、ヘッダ項目の受信者はその(要素の修飾された名前から伝わる)セマンティックスを守り、正しい処理を行わなければならない。あるいは、受信者はメッセージの処理を失敗として終了しなければならない(4.4節を参照)。
SOAP mustUnderstand属性は頑健な(robust)発展を考慮している。値"1"のSOAP mustUnderstand属性でタグ付けされた要素は、その親か関連の要素のセマンティックスを何らかの形で修正しているとみなされなければならない。要素をこのような方法でタグ付けすることにより、このセマンティックスへの変更が変更の意味を理解していないかもしれないアプリケーションによって黙って(もっともらしく、誤って)無視されてしまわないことが保証される。
この属性が有効であるためにはSOAPのメッセージのインスタンス中に現れなければならない(3節と4.2.1節を参照)。
SOAP Body要素は最終的なメッセージの受信者のための必須の情報を交換するための単純なメカニズムを提供する。Body要素の典型的な使用例はRPC呼び出しのマーシャリング(marshalling)やエラーの報告である。
Body要素はSOAP Envelope要素の子要素として符号化される。もしHeader要素が存在する場合にはBody要素はHeader要素の直後に続いていなければならない。そうでなければ、Body要素はEnvelope要素の最初の子要素でなければならない。
Body要素のすべての子要素は本体項目(body entry)と呼ばれ、SOAP Body要素中で独立した要素として符号化される。
本体項目の符号化規則を以下に示す。
SOAPはFault項目という本体項目をエラーを報告するために定義する(4.4節を参照)。
Header要素とBody要素は独立した要素として定義されるが、実際には関係している。本体項目とヘッダ項目の関係は以下のとおりである: 本体項目はデフォルトのactor向けのmustUnderstand属性 "1"を持ったヘッダ項目と意味的には等価である。デフォルトのactorはactor属性を使わないことにより指定される(4.2.2節を参照)。
SOAP Fault要素はSOAPメッセージ中でエラーあるいは状態情報を伝えるために使われる。Fault要素が存在する場合、この要素は本体項目として現れなければならず、Body要素中に2回以上現れてはいけない。
SOAP Fault要素は以下のような子要素を定義する。
名前空間が修飾されているという条件で、他のFault要素の子要素が存在してもよい。
本仕様で定義されている違反を記述するときには本節で定義されているfaultcodeの値がfaultcode要素の中で使われなければならない。これらのfaultcodeの値のための名前空間識別子は"http://schemas.xmlsoap.org/soap/envelope/"である。現状の仕様の外で定義される方式(訳注:例えばHTTP以外のプロトコルとのバインディング等を指しているのか?)の仕様においてもこの空間の使用が推奨されている(しかし要求されてはいない)。
デフォルトのSOAP faultcodeの値は既存のfaultcode値と下位互換性を保ちながら新しいfaultcode値を定義することを考慮して拡張可能なかたちで定義されている。使われているメカニズムは1xx, 2xx, 3xx等々といったHTTPで定義されている"basic status classes"([5]の10節を参照)とよく似ている。しかし、整数の代わりに値はXMLの修飾された名前([8] 3節を参照)として定義されている。文字"." (ドット)がfaultcode値のセパレータとして使われておりドットの左側にあるものが右側の値よりもより一般的な違反コードである。例を以下に示す。
Client.Authentication
この文書中で定義されているfaultcode値の集合を以下に示す。
|
名前 |
意味 |
|
VersionMismatch |
処理当事者がSOAP Envelope要素に対して正しくない名前空間を発見した(4.1.2節を参照)。 |
|
MustUnderstand |
値"1"のmustUnderstand属性を含んだSOAP Header要素の子要素があり、それが理解できないか当事者が意図したように処理されていない(4.2.3節を参照)。 |
|
Client |
Clientクラスのエラーはメッセージが正しく構成されていないか、処理を進める上で適切な情報を含んでいないことを示す。例えば、メッセージに正当な認証や支払いの情報が欠如しているのかもしれない。これはメッセージを修正せずに再送すべきではないことを示す。4.4節のSOAP Fault要素のdetail子要素の記述も参照せよ。 |
|
Server |
Serverクラスのエラーは直接メッセージの内容に起因する原因ではなくメッセージの処理過程に関わる理由でメッセージを処理することができなかったことを示す。例えば、処理の内容が上流のプロセッサとの通信を含んでおり、そのプロセッサが応答しなかったのかもしれない。そのメッセージの処理は後の時点で成功するかもしれない。4.4節のSOAP Fault要素のdetail子要素の記述も参照せよ。 |
SOAPの符号化方式は、プログラミング言語、データベースそして半構造(semi-structured)データにおける型システムに見られる共通の特徴を一般化した簡単な型システムに基づいている。型は、単純型(スカラー型)、あるいは、それぞれ型を持つ複数の部分から構成される複合型のいずれかである。このことは、以下にさらに詳しく述べられている。本節では、型付けされたオブジェクトのグラフの直列化規則を定義する。それは、2つのレベルで機能する。最初のレベルでは、型システムに矛盾しない任意の記法で書かれたスキーマが与えられると、あるXMLスキーマが作成される。次のレベルでは、型システムスキーマとそのスキーマに従うある特定の値のグラフが与えられると、XMLインスタンスが作成される。逆に、この規則に従って生成されたXMLインスタンスおよび元のスキーマが与えられると、元の値のグラフのコピーが作成される。
本節で定義される要素と属性のための名前空間の識別子は、"http://schemas.xmlsoap.org/soap/encoding/"である。
本節で述べられるデータモデルと符号化規則の使用は推奨されるが、要求はされない。他のデータモデルおよび符号化規則も、SOAPと共に使用可能である(4.1.1節参照)。
XMLを用いると非常に柔軟な(flexible)データ符号化が可能である。SOAPはなるべく小さな(narrower)符号化規則群を定義する。本節では、符号化規則をハイレベルで定義し、特定の型に関してより詳細な説明が必要な場合は次の節で述べられる。この節で述べられている符号化規則は、7節で明記されているRPCコールとレスポンスのマッピングと共に使用可能である。
符号化を記述するために、次の用語が用いられる。
値のグラフがその構造および値の型の両方について自己記述的(self-describing)になるようにxsi:type属性を用いることは可能であるが、直列化規則は値の型があるスキーマへの参照によってのみ決定されてもよいことを許可する。そのようなスキーマは"XML Schema Part 1: Structures" [10] と "XML Schema Part 2: Datatypes" [11]で述べられている記法に従ってもよいし、その他の記法に従ってもよい。直列化規則は配列や構造体以外の複合型に適用されるが、多くのスキーマは構造体と配列の型のみを含むことに注意しよう。
直列化のための規則は次のように記述される。
規則2により、独立要素および配列のメンバーを表す要素は、含まれる値の型と異なる名前を持つことが許されることに注意しよう。
単純型に関して、SOAPは"XML Schema Part 2: Datatypes" Specification [11]の"Built-in datatypes"の節に見られるすべての型を、値空間(value space)と構文空間(lexical space)の両方を含めて、採用する。 以下はその例である。
|
型 |
例 |
|
int |
58502 |
|
float |
314159265358979E+1 |
|
negativeInteger |
-32768 |
|
string |
Louis "Satchmo" Armstrong |
XMLスキーマの仕様で宣言されるデータ型は、要素のスキーマにおいて直接使用されるかもしれない。これらから派生する型もまた使用されるかもしれない。これらの型を持つ要素のスキーマフラグメントと対応するインスタンスデータの例を以下にあげる。
<element name="age" type="int"/>
<element
name="height" type="float"/>
<element name="displacement"
type="negativeInteger"/>
<element
name="color">
<simpleType
base="xsd:string">
<enumeration
value="Green"/>
<enumeration
value="Blue"/>
</simpleType>
</element>
<age>45</age>
<height>5.9</height>
<displacement>-450</displacement>
<color>Blue</color>
すべての単純値は要素の内容として符号化されなければならず、その型は"XML Schema Part 2: Datatypes" Specification [11]で定義されている型、あるいは、XMLスキーマの仕様で与えられるメカニズムを用いることによって得られる型のいずれかに基づいていなければならない。
もし単純値が独立要素あるいは異種の配列のメンバーとして符号化されるならば、データ型に対応する要素宣言があると便利である。 "XML Schema Part 2: Datatypes" Specification [11]は型定義を含むが、それに対応する要素宣言は含まないので、SOAP-ENCスキーマと名前空間はあらゆるデータ型に対応する要素を宣言する。これらが使われてもよい。
<SOAP-ENC:int id="int1">45</SOAP-ENC:int>
データ型「文字列(string)」は"XML Schema Part 2: Datatypes" Specification [11]で定義されている。これは多くのデータベースあるいはプログラミング言語において"string"と呼ばれる型とは異なり、特に、それらの言語が許すいくつかの文字の使用を禁止しているかもしれないことに注意しよう(それらの値はxsd:string以外のなんらかのデータ型を用いて表現されなけらばならない)。
文字列は単一参照値あるいは多重参照値として符号化されてもよい。
文字列を含んでいる要素は"id"属性を持ってもよい。その場合、追加のアクセサ要素はそれにマッチする"href"属性を持ってもよい。
例えば、同じ文字列を指す2つのアクセサが次のように現れうる。
<greeting id="String-0">Hello</greeting>
<salutation href="#String-0"/>
しかしながら、両方のアクセサが文字列型(あるいは文字列の子型(subtype))の同じインスタンスを参照しているという事実が重要でないなら、それらは次のように2つの単一参照値として符号化されてもよい。
<greeting>Hello</greeting>
<salutation>Hello</salutation>
これらの例のためのスキーマフラグメントは以下と同様のものになるだろう。
<element name="greeting"
type="SOAP-ENC:string"/>
<element name="salutation"
type="SOAP-ENC:string"/>
(この例では、SOAP-ENC:string型は要素の型として使用されており、これは、データ型が"xsd:string"であり、かつ、"id"および"href"属性を許す要素を宣言する便利な方法である。正確な定義についてはSOAP符号化スキーマを参照のこと。スキーマはSOAP符号化スキーマからこれらの宣言を用いてもよいが、要求はされない。
"XML Schema Part 2: Datatypes" Specification [11]は「列挙(enumeration)」と呼ばれるメカニズムを定義している。SOAPデータモデルはこのメカニズムをそのまま採用する。しかしながら、プログラミングおよび他の言語はしばしば幾分異なった形で列挙を定義しているので、我々はここでその概念をより詳しく説明し、可能な値が列挙されたリストのメンバーの値がどのように符号化されるかを述べる。厳密に言えば、それは値の名前として符号化される。
1つの概念として列挙は異なる名前の集合を指す。特定の列挙は 基本となる型に適した異なる値の特定のリストである。例えば、色の名前の集合 ("Green", "Blue", "Brown")は組み込みの(built-in)文字列型に基づく列挙として定義される。値("1", "3", "5")は整数に基づくありうる列挙である、など。"XML Schema Part 2: Datatypes" [11]は ブール型(boolean)を除くすべての単純型の列挙をサポートしている。 "XML Schema Part 1: Structures" Specification [10]の言語を、列挙型を定義するために用いることができる。 もしスキーマが、特定の基本型が利用できないような別の記法により生成されるならば、「文字列(string)」を用いればよい。以下のスキーマの例では、"EyeColor"は"Green", "Blue", あるいは"Brown"を可能な値として持つ文字列として定義されており、インスタンスデータがそれに従って示されている。
<element name="EyeColor"
type="tns:EyeColor"/>
<simpleType name="EyeColor"
base="xsd:string">
<enumeration
value="Green"/>
<enumeration
value="Blue"/>
<enumeration
value="Brown"/>
</simpleType>
<Person>
<Name>Henry
Ford</Name>
<Age>32</Age>
<EyeColor>Brown</EyeColor>
</Person>
バイト配列は単一参照値あるいは多重参照値として符号化されてもよい。バイト配列に関する規則は、文字列に関する規則に似ている。
特に、バイト配列を含む要素は"id"属性を持ってもよい。その場合、追加のアクセサ要素はそれにマッチする"href"属性を持ってもよい。
内容が見えない(opaque)バイト配列の推奨される表現は、XMLスキーマ [10][11]で定義されているbase64符号化であり、それはRFC2045 [13]で定義されているbase64符号化アルゴリズムを用いている。しかしながら、MIMEにおいてbase64データに適用される行の長さの制限は、SOAPでは適用されない。"SOAP-ENC:base64"子型(subtype)はSOAPでの使用のために提供されている。
<picture
xsi:type="SOAP-ENC:base64">
aG93IG5vDyBicm73biBjb3cNCg==
</picture>
多くの言語は複数の型、それぞれの型は実行時に確定される、の値に多態的にアクセスできるアクセサを許している。多態的アクセサのインスタンスは実際の値の型を表現する"xsi:type"属性を含まなけれならない。
例えば、"xsd:float"型の値をとる"cost"という名前の多態的アクセサは次のように符号化されうる。
<cost xsi:type="xsd:float">29.95</cost>
これは、次のように値の型が不変なcostアクセサとは対照的である。
<cost>29.95</cost>
SOAP は、プログラミング言語にしばしば見られるような次の構造パターンに対応する型を定義する。
SOAP は構造体でも配列でもないデータの直列化も許す。例えば、1つのノードが多くの異なるアクセサを持ち、その中には2度以上出現するものもある有向ラベル付けグラフデータモデルで見られるようなデー タがある。SOAP の直列化はアクセサを順序付けして区別する基礎となるデータモデルを必要としないが、もしそのような順序が存在するなら、そのアクセサはその並び順で符号化されなければならない。
複合値のメンバーはアクセサ要素として符号化される。アクセサが (例えば構造体における場合のように) 名前で区別される場合、そのアクセサ名は要素名として使われる。名前がそれらを含む型に対して局所的なアクセサは修飾されない要素名を持ち、その他すべてのものは修飾された名前を持つ。
次の例は "Book" 型の構造体の例である。
<e:Book>
<author>Henry Ford</author>
<preface>Prefatory text</preface>
<intro>This is a book.</intro>
</e:Book>
そして、これは前述の構造を記述するスキーマフラグメントである。
<element name="Book">
<complexType>
<element name="author" type="xsd:string"/>
<element name="preface" type="xsd:string"/>
<element name="intro" type="xsd:string"/>
</complexType>
</element>
次は単純なメンバーと複雑なメンバーの両方を持つ型の例である。それは2つのレベルの参照を表している。"Author" アクセサ要素の"href" 属性は、その "id" 属性がマッチする値への参照であることに注意しよう。同様の構造は "Address" にも見られる。
<e:Book>
<title>My Life and Work</title>
<author href="#Person-1"/>
</e:Book>
<e:Person id="Person-1">
<name>Henry Ford</name>
<address href="#Address-2"/>
</e:Person>
<e:Address id="Address-2">
<email>mailto:henryford@hotmail.com</email>
<web>http://www.henryford.com</web>
</e:Address>
前述の形式は "Person" の値と "Address" の値が多重参照である場合に適切なものである。もしそうではなくて両方とも単一参照であるなら、これらは次のように埋め込まれるべきである。
<e:Book>
<title>My Life and Work</title>
<author>
<name>Henry Ford</name>
<address>
<email>mailto:henryford@hotmail.com</email>
<web>http://www.henryford.com</web>
</address>
</author>
</e:Book>
もしそうではなくて与えられた例においていかなる2人の人も同一の住所を持つことができず、住所は Street-address であっても Electronic-addressであってもよいという制限が存在するなら、2人の著者を持つ Book は次のように符号化されるだろう。
<e:Book>
<title>My Life and Work</title>
<firstauthor href="#Person-1"/>
<secondauthor href="#Person-2"/>
</e:Book>
<e:Person id="Person-1">
<name>Henry Ford</name>
<address xsi:type="m:Electronic-address">
<email>mailto:henryford@hotmail.com</email>
<web>http://www.henryford.com</web>
</address>
</e:Person>
<e:Person id="Person-2">
<name>Samuel Crowther</name>
<address xsi:type="n:Street-address">
<street>Martin Luther King Rd</street>
<city>Raleigh</city>
<state>North Carolina</state>
</address>
</e:Person>
直列化は同じリソース内にない値への参照を含むことができる。
<e:Book>
<title>Paradise Lost</title>
<firstauthor href="http://www.dartmouth.edu/‾milton/"/>
</e:Book>
またこれは前述の構造を記述するスキーマフラグメントである。
<element name="Book" type="tns:Book"/>
<complexType name="Book">
<!-- Either the following group must occur or else the
href attribute must appear, but not both. -->
<sequence minOccurs="0" maxOccurs="1">
<element name="title" type="xsd:string"/>
<element name="firstauthor" type="tns:Person"/>
<element name="secondauthor" type="tns:Person"/>
</sequence>
<attribute name="href" type="uriReference"/>
<attribute name="id" type="ID"/>
<anyAttribute namespace="##other"/>
</complexType>
<element name="Person" base="tns:Person"/>
<complexType name="Person">
<!-- Either the following group must occur or else the
href attribute must appear, but not both. -->
<sequence minOccurs="0" maxOccurs="1">
<element name="name" type="xsd:string"/>
<element name="address" type="tns:Address"/>
</sequence>
<attribute name="href" type="uriReference"/>
<attribute name="id" type="ID"/>
<anyAttribute namespace="##other"/>
</complexType>
<element name="Address" base="tns:Address"/>
<complexType name="Address">
<!-- Either the following group must occur or else the
href attribute must appear, but not both. -->
<sequence minOccurs="0" maxOccurs="1">
<element name="street" type="xsd:string"/>
<element name="city" type="xsd:string"/>
<element name="state" type="xsd:string"/>
</sequence>
<attribute name="href" type="uriReference"/>
<attribute name="id" type="ID"/>
<anyAttribute namespace="##other"/>
</complexType>
SOAPの配列は "SOAP-ENC:Array" 型またはそれらから派生した型(規則 8 も参照)を持つものとして定義される。配列は要素の値で表現され、その上位の要素の名前に特別な制限はない(値が一般的に上位の要素の名前を制限しないように)。
配列は任意の型を持ちうる要素 (これにはネストされた配列が含まれる) を含むことができる。例えば整数に限定された配列やユーザが定義したある列挙型の配列などを表現するために、SOAP-ENC:Array の制限を使って形成された新しい型を作ることもできる。
配列値の表現は、その配列の項目になる要素の順序付き列である。ある配列値の中では、要素名はアクセサを区別するのに重要な意味は持たない。要素は任意の名前を持ってもよい。実際には、要素はスキーマでのそれらの宣言がそれらの型を示唆あるいは決定するように名付けられることが多いだろう。一般に複合型に関しては、その配列内の項目の値が単一参照値なら、その項目はその値を含む。さもなければ、その項目は"href"属性を通じてその値を参照する。
次の例はスキーマフラグメントと整数配列メンバーを含む配列である。
<element name="myFavoriteNumbers"
type="SOAP-ENC:Array"/>
<myFavoriteNumbers
SOAP-ENC:arrayType="xsd:int[2]">
<number>3</number>
<number>4</number>
</myFavoriteNumbers>
この例では、配列 "myFavoriteNumbers" は、それぞれが SOAP-ENC:int 型の値である複数のメンバーを含む。これは SOAP-ENC:arrayType 属性を調べることによって決定できる。SOAP-ENC:Array型が、修飾されない要素名を、無制限に許すことに注意しよう。これらは型情報を持たないので、使うときは、それらがxsi:type属性を持つか、その上位の要素がSOAP-ENC:arrayType属性を持たなければならない。当然、SOAP-ENC:Arrayから派生した型は型情報付きの局所要素を宣言してもよい。
前述のとおり、SOAP-ENCスキーマは「XML Schema Part 2: Datatypes」仕様[11]における各単純型に対応する名前を持った要素の宣言を含む。それは「配列」の宣言も含む。これらを使うと、次のように書ける。
<SOAP-ENC:Array SOAP-ENC:arrayType="xsd:int[2]">
<SOAP-ENC:int>3</SOAP-ENC:int>
<SOAP-ENC:int>4</SOAP-ENC:int>
</SOAP-ENC:Array>
配列は、指定されたarrayTypeの任意の子型のインスタンスを含むことができる。すなわち、そのメンバーは、どんな代用可能性規則がスキーマで表現されていようともそれにしたがって、arrayType 属性で指定された型に代用可能であるどんな型のものであってもよい。そのため、例えば、整数配列は整数から派生した任意の型 (例えば "int" あるいはどんなユーザ定義の整数の派生) を含むことができる。同様に "address" の配列は "internationalAddress"のような制限された、あるいは拡張された型を含むかもしれない。その供給された SOAP-ENC:Array 型は任意の型のメンバーを許すので、型の任意の混合は arrayType 属性の使用によって特に制限されない限り含むことができる。
メンバー要素の型は、次の2つの配列がそれぞれ示すように、そのインスタンスにおける xsi:type 属性を使って、あるいはそのメンバー要素のスキーマにおける宣言によって指定できる。
<SOAP-ENC:Array SOAP-ENC:arrayType="xsd:ur-type[4]">
<thing xsi:type="xsd:int">12345</thing>
<thing xsi:type="xsd:decimal">6.789</thing>
<thing xsi:type="xsd:string">
Of Mans First Disobedience, and the Fruit
Of that Forbidden Tree, whose mortal tast
Brought Death into the World, and all our woe,
</thing>
<thing xsi:type="xsd:uriReference">
http://www.dartmouth.edu/‾milton/reading_room/
</thing>
</SOAP-ENC:Array>
<SOAP-ENC:Array SOAP-ENC:arrayType="xsd:ur-type[4]">
<SOAP-ENC:int>12345</SOAP-ENC:int>
<SOAP-ENC:decimal>6.789</SOAP-ENC:decimal>
<xsd:string>
Of Mans First Disobedience, and the Fruit
Of that Forbidden Tree, whose mortal tast
Brought Death into the World, and all our woe,
</xsd:string>
<SOAP-ENC:uriReference>
http://www.dartmouth.edu/‾milton/reading_room/
</SOAP-ENC:uriReference >
</SOAP-ENC:Array>
配列の値は構造体や他の複合値であってもよい。例えば、"xyz:Order"構造体の配列は次のようになる。
<SOAP-ENC:Array SOAP-ENC:arrayType="xyz:Order[2]">
<Order>
<Product>Apple</Product>
<Price>1.56</Price>
</Order>
<Order>
<Product>Peach</Product>
<Price>1.48</Price>
</Order>
</SOAP-ENC:Array>
配列はメンバー値として他の配列を持つことができる。次の例は、それぞれが文字列配列である2つの配列の配列である。
<SOAP-ENC:Array SOAP-ENC:arrayType="xsd:string[][2]">
<item href="#array-1"/>
<item href="#array-2"/>
</SOAP-ENC:Array>
<SOAP-ENC:Array id="array-1" SOAP-ENC:arrayType="xsd:string[2]">
<item>r1c1</item>
<item>r1c2</item>
<item>r1c3</item>
</SOAP-ENC:Array>
<SOAP-ENC:Array id="array-2" SOAP-ENC:arrayType="xsd:string[2]">
<item>r2c1</item>
<item>r2c2</item>
</SOAP-ENC:Array>
配列の値を含む要素は "SOAP-ENC:Array"と名付けられる必要はない。もしその要素の型が SOAP-ENC:Arrayであるか、制限(訳注:XMLスキーマのrestriction)に従って SOAP-ENC:Array から派生しているならば、それは任意の名前を持ってもよい。例えば、次はスキーマフラグメントとそれに適合するインスタンス配列である。
<simpleType name="phoneNumber" base="string"/>
<element name="ArrayOfPhoneNumbers">
<complexType base="SOAP-ENC:Array">
<element name="phoneNumber" type="tns:phoneNumber" maxOccurs="unbounded"/>
</complexType>
<anyAttribute/>
</element>
<xyz:ArrayOfPhoneNumbers SOAP-ENC:arrayType="xyz:phoneNumber[2]">
<phoneNumber>206-555-1212</phoneNumber>
<phoneNumber>1-888-123-4567</phoneNumber>
</xyz:ArrayOfPhoneNumbers>
配列は多次元であってもよい。この場合、arrayType属性のasize部分には、2つ以上の大きさを表す数字が現れるだろう。
<SOAP-ENC:Array SOAP-ENC:arrayType="xsd:string[2,3]">
<item>r1c1</item>
<item>r1c2</item>
<item>r1c3</item>
<item>r2c1</item>
<item>r2c2</item>
<item>r2c3</item>
</SOAP-ENC:Array>
前述の例では独立した要素として符号化された配列を示したが、配列値は埋め込んでもよく、それらが単一参照だと分かっている場合にはそのようにすべきである。
次に示すのは、スキーマフラグメントおよび"Person" 型の構造体に埋め込まれる電話番号の配列であり、その配列は"phone-numbers"(訳注:"phoneNumbers"が正しいと思われる)アクセサを通じてアクセスされる。
<simpleType name="phoneNumber"
base="string"/>
<element name="ArrayOfPhoneNumbers">
<complexType base="SOAP-ENC:Array">
<element name="phoneNumber" type="tns:phoneNumber" maxOccurs="unbounded"/>
</complexType>
<anyAttribute/>
</element>
<element name="Person">
<complexType>
<element name="name" type="string"/>
<element name="phoneNumbers" type="tns:ArrayOfPhoneNumbers"/>
</complexType>
</element>
<xyz:Person>
<name>John Hancock</name>
<phoneNumbers SOAP-ENC:arrayType="xyz:phoneNumber[2]">
<phoneNumber>206-555-1212</phoneNumber>
<phoneNumber>1-888-123-4567</phoneNumber>
</phoneNumbers>
</xyz:Person>
上位の要素名がアクセサ名である埋め込み要素として符号化された単一参照配列値の別の例を示す。
<xyz:PurchaseOrder>
<CustomerName>Henry Ford</CustomerName>
<ShipTo>
<Street>5th Ave</Street>
<City>New York</City>
<State>NY</State>
<Zip>10010</Zip>
</ShipTo>
<PurchaseLineItems SOAP-ENC:arrayType="Order[2]">
<Order>
<Product>Apple</Product>
<Price>1.56</Price>
</Order>
<Order>
<Product>Peach</Product>
<Price>1.48</Price>
</Order>
</PurchaseLineItems>
</xyz:PurchaseOrder>
SOAP は、ある状況[12]ではvarying配列として知られる、部分的に転送される配列をサポートする。部分的に転送される配列は "SOAP-ENC:offset" 属性において転送される最初の要素のゼロ基点 (zero-origin) オフセットを示す。もしそれが省略された場合は、そのオフセットはゼロとみなされる。
次の例は、ゼロから数えて3番目と4番目の要素を転送する大きさ5の配列である。
<SOAP-ENC:Array SOAP-ENC:arrayType="xsd:string[5]" SOAP-ENC:offset="[2]">
<item>The third element</item>
<item>The fourth element</item>
</SOAP-ENC:Array>
SOAP は疎な配列をサポートする。メンバー値を表す各要素は配列の中でのその位置を示す "SOAP-ENC:position" 属性を含む。次の例は文字列の2次元配列の疎な配列である。その大きさは4 だが、2番目だけが使われている。
<SOAP-ENC:Array SOAP-ENC:arrayType="xsd:string[,][4]">
<SOAP-ENC:Array href="#array-1" SOAP-ENC:position="[2]"/>
</SOAP-ENC:Array>
<SOAP-ENC:Array id="array-1" SOAP-ENC:arrayType="xsd:string[10,10]">
<item SOAP-ENC:position="[2,2]">Third row, third col</item>
<item SOAP-ENC:position="[7,2]">Eighth row, third col</item>
</SOAP-ENC:Array>
もし array-1 への参照だけが閉じた配列中に出現するなら、この例は次のようにも符号化できるだろう。
<SOAP-ENC:Array SOAP-ENC:arrayType="xsd:string[,][4]">
<SOAP-ENC:Array SOAP-ENC:position="[2]" SOAP-ENC:arrayType="xsd:string[10,10]>
<item SOAP-ENC:position="[2,2]">Third row, third col</item>
<item SOAP-ENC:position="[7,2]">Eighth row, third col</item>
</SOAP-ENC:Array>
</SOAP-ENC:Array>
今示した符号化の規則はアクセサ名があらかじめ分かる場合に限らない。もしアクセサ名が、符号化されるべき直下の値 (immediate values) の検査によってのみ分かるなら、同じ規則が適用される。すなわち、名前はそのアクセサ名にマッチする要素として符号化され、そのアクセサはその値を含むか参照する。型があらかじめ決められない値を含むアクセサは、その値の型を与える適切な xsi:type 属性を常に含まなければならない。
同様に、名前によって区別されるアクセサと名前と順序を示す位置の両方によって区別されるアクセサを合わせ持つ(すなわち、いくつかのアクセサの繰り返しを持つ)。複合型の直列化を可能にするのに、ここに示した規則は十分である。このことから、どんなスキーマでもそのような型を実際に含むことが必要になるわけではないが、むしろ、もし型モデルのスキーマがそのような型を持つなら、対応する XML 構文スキーマとインスタンスを生成してもよいということが言える。
<xyz:PurchaseOrder>
<CustomerName>Henry Ford</CustomerName>
<ShipTo>
<Street>5th Ave</Street>
<City>New York</City>
<State>NY</State>
<Zip>10010</Zip>
</ShipTo>
<PurchaseLineItems>
<Order>
<Product>Apple</Product>
<Price>1.56</Price>
</Order>
<Order>
<Product>Peach</Product>
<Price>1.48</Price>
</Order>
</PurchaseLineItems>
</xyz:PurchaseOrder>
同様に、配列に構造上似ているが SOAPーENC:Array 型 (または子型) の値ではない複合値を直列化することは有効である。例えば、
<PurchaseLineItems>
<Order>
<Product>Apple</Product>
<Price>1.56</Price>
</Order>
<Order>
<Product>Peach</Product>
<Price>1.48</Price>
</Order>
</PurchaseLineItems>
アクセサ要素を省略した場合はデフォルト値か不明値のどちらかの意味になる。その正確なところは、そのアクセサ、メソッド、その文脈に依存する。例えば、アクセサを省略した場合は普通は多態的アクセサの Null 値 (正確には Null アクセサに依存) の意味になる。同様に、ブール型アクセサを省略した場合は普通は偽値か不明値のどちらかの意味になり、数値アクセサを省略した場合は普通はゼロか不明値のどちらかの意味になる。
オブジェクトグラフが直列化を元に戻せるようにそのオブジェクトグラフの真のルートではない直列化ルートをラベル付けするために、SOAPのroot属性が使われる。その属性は"1"または"0"の2つの値の1つを持つことができる。オブジェクトグラフの真のルートは暗黙の属性値"1"を持つ。真のルートではない直列化ルートは属性値 "1" を持つ直列化ルートとしてラベル付けできる。要素は、値"0"を持つ直列化ルートではないものとして、明示的にラベル付けできる。
SOAPのroot属性はSOAP Header要素とSOAP Body要素の中の任意の子要素に現れてよい。その属性はデフォルト値を持たない。
この節では、HTTPにおいてSOAPを使用する方法について、 HTTP拡張フレームワーク(Extension Framework)を使用する場合と使用しない 場合に分けて説明する。 SOAPをHTTPとバインドすることによって、 SOAPの形式化と非集中の柔軟性を、HTTPの豊富な 特徴と共に使用することができる。 HTTPでSOAPを運ぶことは、SOAPが既存のHTTPのセマンティクスを覆すというこ とではなく、むしろHTTP上のSOAPのセマンティクスをHTTPのセマンティクスに 自然な形で対応することを意味する。
SOAPリクエストパラメータをHTTPリクエストで 提供し、SOAPレスポンスパラメータをHTTPレスポンスで提供することで、 SOAPは、HTTPリクエスト/レスポンスメッセージモデルに自然な形で従う。 ただし、SOAPの仲介者は、HTTPのそれとは異なることに注意する。 即ち、HTTP Connectionヘッダフィールドで指定されたHTTPの仲介者は、 HTTPリクエストで運ばれるSOAPエンティティを検査したり、 処理したりすることを期待されない。
HTTPアプリケーションは、HTTPメッセージにSOAPエンティティを 含む場合に、RFC 2376 [3]に従って、メディアタイ プ"text/xml"を使用しなければならない。
SOAPは様々なHTTPリクエストメソッドと組み合わせて使 用されるかもしれないが、このバインディングではHTTP POSTリクエストにお けるSOAPを定義するだけである(RPCのためにSOAPを使用する方法については7節を、HTTP拡張フレームワークを使用する方法 については6.3節を参照)。
SOAPAction HTTPリクエストヘッダフィールドは、 SOAP HTTPリクエストの意図を指示するために使用される。 その値は、意図を識別するURIである。 SOAPは、URIの形式や書式、解決可能であることなどに対して制限を加えていない。 HTTPクライアントは、SOAP HTTPリクエストを発行するときに、このヘッダフィー ルドを使用しなければならない。
soapaction = "SOAPAction" ":"
[ <"> URI-reference <"> ]
URI-reference = <as
defined in RFC 2396 [4]>
SOAPActionヘッダフィールドの存在や内容は、 HTTPにおけるSOAPリクエストメッセージを適切にフィルタリングするファイア ウォールなどのサーバによって使用される。 ヘッダフィールドの値が空文字("")である場合は、SOAPメッセージの意図が HTTP Request-URIによって指示されることを意味する。 値自体がない場合は、メッセージの意図に対する指示がないことを意味する。
例:
SOAPAction:
"http://electrocommerce.org/abc#MyMessage"
SOAPAction:
"myapp.sdl"
SOAPAction: ""
SOAPAction:
SOAP HTTPは、HTTPにおける状態情報を通知するために、 HTTP状態コードのセマンティクスに従う。 例えば、状態コード2xxは、 クライアントが送信したSOAPコンポーネントを含 むリクエストの受信や解釈、受理などが成功したことを示す。
リクエストを処理している間にSOAPエラーが発生した場 合、SOAP HTTPサーバはHTTPレスポンス500 "Internal Server Error"を発行す ると同時に、そのレスポンスは、SOAP処理エラーを示すSOAP Fault要素(4.4節を参照)を持つSOAPメッセージを含まな ければならない。
SOAP HTTPリクエストの存在と意図を識別するために、 SOAPメッセージをHTTP拡張フレームワーク[6]と共に 使用してもよい。
拡張フレームワークと通常のHTTPのどちらを使用するか は、通信の当事者のポリシーと能力に依存する。 クライアントは、必須拡張宣言(mandatory extension declaration)とHTTPメ ソッド名接頭辞"M-"を使用することで、HTTP拡張フレームワークの使用を強要 できる。 サーバは、HTTP状態コード510 "Not Extended"を使用することで、HTTP拡張フ レームワークの使用を強要できる。 即ち、一度だけ余分に通信を行うことで、一方は他方のポリシーを検出し、そ れに従って行動できる。
拡張フレームワークを使用するSOAPを識別するために使 用される拡張識別子(extension identifier)は、以下の通りである。
http://schemas.xmlsoap.org/soap/envelope/
例3 POSTを使用するSOAP HTTP
POST /StockQuote HTTP/1.1
Content-Type: text/xml;
charset="utf-8"
Content-Length: nnnn
SOAPAction:
"http://electrocommerce.org/abc#MyMessage"
<SOAP-ENV:Envelope...
HTTP/1.1
200 OK
Content-Type: text/xml; charset="utf-8"
Content-Length:
nnnn
<SOAP-ENV:Envelope...
例4 HTTP拡張フレームワークを使用するSOAP
M-POST /StockQuote HTTP/1.1
Man:
"http://schemas.xmlsoap.org/soap/envelope/"; ns=NNNN
Content-Type: text/xml;
charset="utf-8"
Content-Length: nnnn
NNNN-SOAPAction:
"http://electrocommerce.org/abc#MyMessage"
<SOAP-ENV:Envelope...
HTTP/1.1
200 OK
Ext:
Content-Type: text/xml; charset="utf-8"
Content-Length:
nnnn
<SOAP-ENV:Envelope...
SOAPの設計目標の一つは、XMLの拡張性と柔軟性を使用し て、RPCコールをカプセル化し、交換することである。 この節では、RPCコールとレスポンスの統一的な表現を定義する。
この表現は5節で定義さ れた符号化方式と組み合わせて使用されると予想されるが、別の表現も可能で ある。 SOAP encodingStyle属性(4.3.2節を参照)は、 この節で述べられる表現を使用して、メソッドコールとレスポンスの符号化方 式を指示するために使用される。
RPCのためにSOAPを使用することは、SOAPプロトコルバイ ンディング(6節を参照)と直交する。 プロトコルバインディングとしてHTTPを使用する場合、RPCコールはHTTPリク エストに、RPCレスポンスはHTTPレスポンスに自然な形で対応する。 しかし、RPCのためにSOAPを使用することは、HTTPプロトコルバインディング に限定されない。
メソッドコールを実行するには、以下の情報が必要であ る。
SOAPは、プロトコルバインディングに依存して、URIを運 ぶための機構を提供する。 例えば、HTTPでは、リクエストURIが呼び出されるリソースを示す。 SOAPは、URIが正当であること以外に、アドレス形式 に対して制限を加えていない(URIについての詳細は、[4]を参照)。
RPCメソッドコールとレスポンスは共に、以下の表現を使 用して、SOAP Body要素( 4.3節を参照)で運ばれる。
前述のように、メソッドとレスポンスの構造体 は、5節の規則に従って符号化される。 そうでなければ、encodingStyle属性(4.1.1節 を参照)を使用して、別の符号化が指定される。
アプリケーションは、パラメータが欠けた状態でリクエ ストを処理してもよいし、違反を返してもよい。
結果は成功を示し、違反は失敗を示すため、メソッドレ スポンスが結果と違反を共に含むことはエラーである。
メソッドリクエストの符号化に関係するが、正式なメソッ ドシグニチャの一部ではない付加的な情報を、RPC符号化で表現してもよい。 その場合には、SOAP Header要素の子要素として、その情報を表現しなければな らない。
ヘッダ要素を使用する例として、メッセージに沿ったト ランザクション識別子の受け渡しがある。 トランザクション識別子はシグニチャの一部ではなく、通常はアプリケーショ ンコードよりもむしろ基盤となるコンポーネントの内部に保持されるため、コー ルで必要な情報を手渡す直接的な方法はない。 ヘッダに項目を追加し、決められた名前を付与することで、 RPCの符号化に影響を及ぼさずに、受信側のトランザクション管理者は トランザクション識別子を抽出し、使用することがで きる。
このドキュメントには、 完全性(integrity)とプライバシー保護に対する方法が述べら れていない。 そのような問題は、このドキュメントの将来版で、 もっと詳しく述べられるだろう。
[1] S. Bradner, "The Internet Standards Process -- Revision 3", RFC2026, Harvard University, October 1996
[2] S. Bradner, "Key words for use in RFCs to Indicate Requirement Levels", RFC 2119, Harvard University, March 1997
[3] E. Whitehead, M. Murata, "XML Media Types", RFC2376, UC Irvine, Fuji Xerox Info. Systems, July 1998
[4] T. Berners-Lee, R. Fielding, L. Masinter, "Uniform Resource Identifiers (URI): Generic Syntax", RFC 2396, MIT/LCS, U.C. Irvine, Xerox Corporation, August 1998.
[5] R. Fielding, J. Gettys, J. C. Mogul, H. Frystyk, T. Berners-Lee, "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2616, U.C. Irvine, DEC W3C/MIT, DEC, W3C/MIT, W3C/MIT, January 1997
[6] H. Nielsen, P. Leach, S. Lawrence, "An HTTP Extension Framework", RFC 2774, Microsoft, Microsoft, Agranat Systems
[7] W3C Recommendation "The XML Specification"
[8] W3C Recommendation "Namespaces in XML"
[9] W3C Working Draft "XML Linking Language". This is work in progress.
[10] W3C Working Draft "XML Schema Part 1: Structures". This is work in progress.
[11] W3C Working Draft "XML Schema Part 2: Datatypes". This is work in progress.
[12] Transfer Syntax NDR, in "DCE 1.1: Remote Procedure Call"
[13] N. Freed, N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies", RFC2045, Innosoft, First Virtual, November 1996
POST /StockQuote HTTP/1.1
Host:
www.stockquoteserver.com
Content-Type: text/xml;
charset="utf-8"
Content-Length: nnnn
SOAPAction:
"Some-URI"
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
<SOAP-ENV:Header>
<t:Transaction
xmlns:t="some-URI"
SOAP-ENV:mustUnderstand="1">
5
</t:Transaction>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<m:GetLastTradePrice
xmlns:m="Some-URI">
<symbol>DEF</symbol>
</m:GetLastTradePrice>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
例6 例1と同様であるが、複数のリクエストパラメータを含む場合
POST /StockQuote HTTP/1.1
Host:
www.stockquoteserver.com
Content-Type: text/xml;
charset="utf-8"
Content-Length: nnnn
SOAPAction:
"Some-URI"
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
<SOAP-ENV:Body>
<m:GetLastTradePriceDetailed
xmlns:m="Some-URI">
<Symbol>DEF</Symbol>
<Company>DEF
Corp</Company>
<Price>34.1</Price>
</m:GetLastTradePriceDetailed>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
HTTP/1.1 200 OK
Content-Type: text/xml;
charset="utf-8"
Content-Length:
nnnn
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
<SOAP-ENV:Header>
<t:Transaction
xmlns:t="some-URI"
xsi:type="xsd:int" mustUnderstand="1">
5
</t:Transaction>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<m:GetLastTradePriceResponse
xmlns:m="Some-URI">
<Price>34.5</Price>
</m:GetLastTradePriceResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
HTTP/1.1 200 OK
Content-Type: text/xml;
charset="utf-8"
Content-Length: nnnn
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
<SOAP-ENV:Body>
<m:GetLastTradePriceResponse
xmlns:m="Some-URI">
<PriceAndVolume>
<LastTradePrice>
34.5
</LastTradePrice>
<DayVolume>
10000
</DayVolume>
</PriceAndVolume>
</m:GetLastTradePriceResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
例9 例2と同様であるが、必須のHeader要素の受け入れに失敗した場合
HTTP/1.1 500 Internal Server Error
Content-Type:
text/xml; charset="utf-8"
Content-Length:
nnnn
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:MustUnderstand</faultcode>
<faultstring>SOAP
Must Understand
Error</faultstring>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
HTTP/1.1 500 Internal Server Error
Content-Type:
text/xml; charset="utf-8"
Content-Length:
nnnn
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Server</faultcode>
<faultstring>Server
Error</faultstring>
<detail>
<e:myfaultdetails
xmlns:e="Some-URI">
<message>
My
application didn't
work
</message>
<errorcode>
1001
</errorcode>
</e:myfaultdetails>
</detail>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>