最終更新日:2011-09-23
この文書はW3Cの公開する文書を独自に翻訳したものです。この仕様書の正式なものはW3Cのサイトにある英語版です。翻訳にはまだ多くの誤りがあることに留意してください。誤訳・誤植を発見された方は管理者(西本卓也)までお知らせください。
正式な文書:Voice eXtensible Markup Language (VoiceXML) version 1.0
日本語版作成:京都工芸繊維大学 電子情報工学科 パターン情報処理研究室
この文書では、VoiceXML(the Voice eXtensible Markup Language)を紹介する。VoiceXMLは音を用いた対話のために設計された。音を用いた対話とは、合成音声、デジタル化された音、音声とDTMFキー入力の認識、入力音声の録音、電話による操作、混合主導型の会話、が利用可能な対話である。VoiceXMLの主な目的はWebベースのシステム開発と情報提供において、相互作用的な音声対話アプリケーションの利用を促すことである。
以下にVoiceXMLの短い例を2つあげる。まずは有名な「Hello World(こんにちは)」である。
<?xml version="1.0"?> <vxml version="1.0"> <form> <block> こんにちは! </block> </form> </vxml>
トップレベルの要素は<vxml>である。これは、主として対話(dialog)を構成要素とする。対話には、与えられた変数の値を得るためのやりとりを定義するフォーム(form)と、ユーザに選択肢を提示しその選択に従って別の対話に遷移するメニュー(menu)の2種類が存在する。この例の対話は1つのフォームからなっており、ユーザに「こんにちは!」という合成音声を返すblockが含まれている。そして後続の対話を指定していないため、これで対話は終了する。
次に飲物の選択をユーザに問い掛け、サーバスクリプトにそれを渡す例文を挙げる。
<?xml version="1.0"?> <vxml version="1.0"> <form> <field name="drink"> <prompt> コーヒー、紅茶、ミルクのうちどれが良いですか? </prompt> <grammar src="drink.gram" type="application/x-jsgf"/> </field> <block> <submit next="http://www.drink.example/drink2.asp"/> </block> </form> </vxml>
fieldは入力フィールドである。ユーザは次の要素に進むために返答しなければならない。
対話例:
C(computer):コーヒー、紅茶、ミルクのうちどれが良いですか?
H(human):オレンジジュース
C:理解できませんでした。
C:コーヒー、紅茶、ミルクのうちどれが良いですか?
H:紅茶
C:(drink2.aspに続く)
この節では高レベルなアーキテクチャモデルについて述べ、次にそこで用いられている用語によって、VoiceXMLの目指すもの、その扱う範囲、設計原理、そしてVoiceXMLをサポートするシステムに対する要求を述べる。
この文書において仮定しているアーキテクチャモデルは以下の要素からなる。
ドキュメントサーバ(例えばWebサーバ)はVoiceXML処理コンテキストを経て渡されたクライアントアプリケーション(VoiceXML処理系)からの要求を処理し、VoiceXMLドキュメントを返す。返されたVoiceXMLドキュメントは、VoiceXML処理系によって処理される。VoiceXML処理コンテキストはVoiceXML処理系と平行してユーザ入力をモニタする。例えば、あるVoiceXML処理コンテキストは、ユーザに高レベルの個人化したアシスト作業を提供するための特別なエスケープフレーズをモニタしている、また別のVoiceXML処理コンテキストは音量や合成音声の種類などのユーザの好みに関するエスケープフレーズをモニタしている。
実装プラットフォームはVoiceXML処理コンテキストとVoiceXML処理系によって制御される。例えば、音声応答アプリケーションでは、VoiceXML処理コンテキストは発呼を検出し、最初のVoiceXMLドキュメントをロードし、応答を行う。一方、VoiceXML処理系は応答後の対話を制御する。実装プラットフォームはユーザによる行為(例:音声や文字の入力、切断)やシステムイベント(例:時間切れ)に応じて、イベントを生成する。これらのうちいくつかはVoiceXMLドキュメントの指定に従って処理系自身により処理され、その他は処理コンテキストで処理される。
VoiceXMLの主な目標は、音声応答アプリケーションのためのWebの開発と、それによる情報提供を盛んにすることであり、アプリケーション製作者を低レベルなプログラミングやリソース管理から解放することである。VoiceXMLによって、親しんだクライアント-サーバパラダイムを用いて、音声サービスとデータサービスが統合できる。音声サービスはユーザと実装プラットフォームとの対話の系列であるとみなすことができる。対話は、実装プラットフォームの外部にあるドキュメントサーバにより供給される。ドキュメントサーバはサービスロジック全体を管理し、データベースなど既存のシステムオペレーションを実行し、対話を生成する。
VoiceXMLドキュメントは、VoiceXML処理系によって行われ相互作用対話を特定する。ユーザ入力は対話の処理に影響を与え、ドキュメントサーバへ返す要求として集められる。ドキュメントサーバは、他の対話によってユーザのセッションを継続するために、新たなVoiceXMLドキュメントを応答して返す。
VoiceXMLは以下のようなマークアップ言語である。
VoiceXMLでは主として音声返答サービスの要求に対応するように進められているが、詳細なレベルの制御を実現しているアプリケーションからの切迫した要求は優先的に取り上げられる。
VoiceXMLは以下の要求を含む音声応答システムにおける人間と機械の相互関係を記述したものである。
VoiceXMLは文字および/または音声による入力を収集し、ドキュメントで定義された変数に入力を割り当て、VoiceXMLで書かれたドキュメントの処理に影響する判定を行う手段を提供する。ドキュメントはURI(Universal Resource Identifier)によって他のドキュメントにリンクされることもある。
VoiceXMLはXMLスキーマである。XMLについての詳細はAnnotated XML Reference Manualを参照のこと。
この節では、VoiceXML処理系をサポートするハードウェア/ソフトウェアプラットフォームへの要求について述べる。
ドキュメント獲得
処理コンテキストは、VoiceXML処理系の実行のため、ドキュメントを要求する。ドキュメント要求はVoiceXMLドキュメントの処理により生成されることもあるし、VoiceXMLの範囲外のイベント(例:着信)に応じて処理コンテキストにより生成されることもある。
音声出力
実装プラットフォームはオーディオファイルやtext-to-speech(TTS)を用いて音声出力が可能である。両方がサポートされている場合、プラットフォームはTTSと音声出力を任意の順序で出力できる必要がある。オーディオファイルは、URIにより参照される、VoiceXMLはオーディオファイルのフォーマットを特に定めない。
音声入力
実装プラットフォームは、文字かつ/または音声による入力を即時に検出し報告する必要があり、VoiceXMLドキュメントにより設定されたタイマーによって入力待ち時間をコントロールできなければならない。
VoiceXMLドキュメント(またはアプリケーションと呼ばれるドキュメントの集合)は対話の有限状態機械を形成する。ユーザはある時点では、1つの対話(dialog)の状態にいることになる。いずれの対話においても次に遷移すべき対話を決定する。遷移は次に使用するドキュメントや対話を定義したURIを使い指定される。もしURIがドキュメントを参照しない場合、現在のドキュメントが参照される。対話を指定しない場合は、ドキュメントの最初の対話が参照される。対話が次の対話を指定していないとき、または明示的に対話を抜ける要素を持つとき、実行が終了する。
対話にはformとmenuの2種類がある。formはフィールド項目変数の集合に与える値を集めるためのやりとりを定義する。それぞれのfieldは、そのfieldにおいて可能な入力を定義する文法を持つことができる。もしformレベルの文法が与えられている場合、それは1つの発話でいくつかのfieldを埋めるために使われる。menuはユーザに選択肢を提示し、その選択に従って別の対話に遷移する。
副対話の単位であるsubdialogは新しいやりとりを呼び出し、元のformに戻るという機能を提供するという点で、関数呼び出しのようなものである。その時点でのデータ、文法、状態の情報は保存され、呼び出したドキュメントに帰ってきたときに利用可能となる。subdialogは例えば次のようなことに使われる。データベース検索の際に必要とされる一連の確認対話の生成、1つのアプリケーション内のドキュメント間で共有されるコンポーネント集合の作成、多くのアプリケーションで共有される再利用可能な対話のライブラリの作成などである。
セッションは、ユーザがVoiceXML処理コンテキストと相互作用を始めたときに始まり、ドキュメントをロードして処理しながら継続し、ユーザ・ドキュメント・処理コンテキストのいずれかの要求によって終了する。
同一のアプリケーションルートドキュメントを共有するドキュメントの集合をアプリケーションと呼ぶ。ユーザがアプリケーション内のドキュメントと相互作用する時には、必ずアプリケーションルートドキュメントもロードされる。同じアプリケーション内のドキュメントをユーザが遷移している間は、アプリケーションルートドキュメントは常にロードされたままであり、アプリケーション外のドキュメントに移ったときに無効になる。ロードされている間は、アプリケーションルートドキュメントの変数はどのドキュメントからもアプリケーション変数として参照可能で、文法はアプリケーションの実行中、常に有効である。
図2は共通のアプリケーションルートドキュメント(root)を共有しているアプリケーション内のドキュメント(D)の遷移を示したものである。
各対話には1つまたは複数の音声認識用文法・DTMF文法が付属している。システム主導のアプリケーションでは、特定の対話の文法は、ユーザがその対話にいるときにのみ有効である。ユーザとコンピュータのいずれかが次に何をするかを決定することができる混合主導型アプリケーションでは、いくつかの対話は、ユーザが同一ドキュメント内の別の対話にいるとき、もしくは同一アプリケーション内の別のロードされたドキュメント内にいるときに、それらの文法をアクティブにする(すなわち、入力を受け付ける)ためのフラグが立てられる。もし、ユーザが他のアクティブな対話の文法に従った発話を行うと、まるでその対話でユーザの発話が行われたかのように制御がその対話に移る。混合主導権は柔軟性を加え、音声アプリケーションの有用性を高める。
VoiceXMLは「標準的な」ユーザ入力を取り扱うためのフォームを埋めるメカニズムを持っている。それに加え、フォームメカニズムによりカバーされないイベントの取り扱いのための機能も持つ。
イベントはユーザが一定時間発話しない、明瞭に応答しない、ヘルプを求めるなどの様々な状況でプラットフォームによって生成される。処理系もまた、VoiceXMLドキュメント内にセマンティックエラーを発見するとイベントを生成する。イベントは、catch要素かその簡略記法によってキャッチされる。イベントを起こすことができる各々の要素は、catch要素で具体的に記述することができる。catch要素は「まるでコピーしたかのように」外側の要素から継承される。このようにして、共通のイベントハンドリング操作は任意のレベルで指定でき、それ以下のすべてのレベルに適用される。
リンクは混合主導型対話を実現する手段の1つである。あるリンクのスコープ内にユーザがいるとき、常にアクティブであるような文法を指定する。その文法にマッチする発話が行われた場合に、リンクで指定したURIへ制御を移す。<link>は、指定のURIに移動するイベントを生成するために使うことができる。
構成要素 | 目的 | 参照 |
---|---|---|
<assign> | 変数に値を割り当てる | 19.2. |
<audio> | プロンプト内部のオーディオクリップを再生する | 13.3. |
<block> | (相互作用のない)実行可能なコードを記述する | 14.2. |
<break> | 出力に無音区間を挿入するJSML構成要素 | 13.2.1. |
<catch> | イベントをキャッチ | 11.2. |
<choice> | メニュー項目の定義 | 7. |
<clear> | form項目変数のクリア | 19.2. |
<disconnect> | セッションを切断 | 19.11. |
<div> | テキストのある範囲を特定のタイプに分類するJSML構成要素 | 13.2.2. |
<dtmf> | プッシュホンキーの文法の指定 | 10.2. |
<else> | <if>内で用いる | 19.4. |
<elseif> | <if>内で用いる | 19.4. |
<emp> | 音声出力の強調度を変えるためのJSML構成要素 | 13.2.3. |
<enumerate> | メニューから中の選択肢を列挙するための簡略記法 | 7. |
<error> | エラーイベントのキャッチ | 11.3. |
<exit> | セッションの終了 | 19.9. |
<field> | form中の入力fieldの宣言 | 14.1. |
<filled> | fieldに値が入ったときに実行する行為 | 15. |
<form> | 情報提供とデータ収集のための対話 | 6. |
<goto> | 同一または別のドキュメントの対話に移動する | 19.7. |
<grammar> | 音声認識文法の指定 | 10. |
<help> | ヘルプイベントのキャッチ | 11.3. |
<if> | 単純な条件分岐 | 19.4. |
<initial> | (混合主導型)formに入るときの初期化ロジックの宣言 | 14.3. |
<link> | リンクスコープ内すべての対話に共通の遷移を指定 | 8. |
<menu> | ユーザに選択肢を提示する対話 | 7. |
<meta> | 名前/値の対形式でメタデータ項目を定義 | 16. |
<noinput> | 入力なしイベントのキャッチ | 11.3. |
<nomatch> | 不一致イベントのキャッチ | 11.3. |
<object> | 拡張機能へのインタフェース | 14.5. |
<option> | <field>内のオプションの指定 | 14.1.3. |
<param> | <object>または<subdialog>内のパラメータ | 18. |
<prompt> | ユーザへのTTSおよびオーディオ出力を行う | 13. |
<property> | 実装プラットフォーム設定の操作 | 17. |
<pros> | 音声出力の韻律変更の為のJSML構成要素 | 13.2.4. |
<record> | オーディオサンプルの録音 | 14.6. |
<reprompt> | イベント後、フィールドが再度訪れられるとき、フィールドのプロンプトを再生する | 19.6. |
<return> | 副対話から戻る | 19.10. |
<sayas> | 単語や句の読み方を変更するJSML構成要素 | 13.2.5. |
<script> | クライアント側のスクリプティングロジックに基づいたECMAScriptの指定 | 19.12. |
<subdialog> | 現在の対話の副対話として、他の対話を呼び出す | 14.4. |
<submit> | ドキュメントサーバに値を渡す | 19.8. |
<throw> | イベントを生成する | 11.1. |
<transfer> | 他の場所へ転送する | 14.7. |
<value> | プロンプト中にexpression(expr)の値を挿入する | 13.4. |
<var> | 変数の宣言 | 19.1. |
<vxml> | VoiceXMLドキュメントの最上位構成要素 | 5. |
VoiceXMLドキュメントは原則として対話と呼ばれる最上位要素から構成される。対話にはformとmenuの二種類がある。ドキュメントは、<meta>要素、<var>と<script>要素、<property>要素、<catch>要素、そして<link>要素などを持つこともある。
1つのドキュメント内の実行
ドキュメントの実行は何も指定がないときは、最初の対話から始まる。対話が実行されると、次の対話が決定される。対話が後続の対話を指定しないとき、ドキュメントの実行は停止する。
"こんにちは!"を拡張してこれを説明する。この例ではあいさつの言葉を保持するドキュメントレベルの変数"hi"を持っている。その値は1番目のformでプロンプトとして使用されている。1番目のformがあいさつを実行すると、ユーザに"さようなら!"と告げる"say_goodbye"という名前のformに移動する。2番目のformは他の対話に遷移する要素を持っていないので、ドキュメントは終了される。
<?xml version="1.0"?> <vxml version="1.0"> <meta name="author" content="工繊 太郎"/> <meta name="maintainer" content="hello-support@hi.example"/> <var name="hi" expr="'こんにちは!'"/> <form> <block> <value expr="hi"/> <goto next="#say_goodbye"/> </block> </form> <form id="say_goodbye"> <block> さようなら! </block> </form> </vxml>
スタイルとしては、これらのformは結合するのが方がよい。
<?xml version="1.0"?> <vxml version="1.0"> <meta name="author" content="工繊 太郎"/> <meta name="maintainer" content="hello-support@hi.example"/> <var name="hi" expr="'こんにちは!'"/> <form> <block> <value expr="hi"/> さようなら! </block> </form> </vxml>
<vxml>の属性を以下に示す。
version | ドキュメントのVoiceXMLのバージョン(必須)。最初のバージョンは1.0。 |
base | ベースとなるURI。 |
lang | このドキュメントの言語とlocaleタイプ。 |
application | (もしあれば)このドキュメントのアプリケーションルートドキュメントのURI。 |
複数ドキュメントアプリケーションの実行
通常はそれぞれのドキュメントは単独のアプリケーションとして実行する。複数のドキュメントを1つのアプリケーションとして動作させたい場合は、1つのドキュメントをアプリケーションルートドキュメントとして選択し、他のドキュメントの<vxml>のapplication属性にアプリケーションルートドキュメントのURIを指定すればよい。
このような場合は、処理系はこのアプリケーション内のドキュメントを読みこむたびに、アプリケーションルートドキュメントが未だ読み込まれていないなら、それを読みこむ。アプリケーションルートドキュメントは、処理系が異なるアプリケーションに属するドキュメントをロードするまでロードされたままになっている。したがって下記の2つの条件のうち1つは、処理の間、常に成立する。
複数ドキュメントからなるアプリケーションには2つの利点がある。1つは、アプリケーションルートドキュメントの変数がアプリケーション内の他のドキュメントで使用することができるため、情報の共有と保持が可能である。もう1つは、ユーザが他のアプリケーションドキュメントにいるときでも、アプリケーションルートドキュメントの文法が有効であるため、ユーザは常に共通のform、link、menuで会話することができる。
以下に「2つのドキュメントからなるアプリケーション」の例を示す。
アプリケーションルートドキュメント(app-root.vxml)
<xml version="1.0"?> <vxml version="1.0"> <var name="bye" expr="'ちゃら'"/> <link next="operator_xfer.vxml"> <grammar> オペレータ </grammar> </link> </vxml>
メインドキュメント(main.vxml)
<?xml version="1.0"?> <vxml version="1.0" application="app-root.vxml"> <form id="say_goodbye"> <field name="answer" type="boolean"> <prompt> <value expr="application.bye"/> にしましょうか </prompt> <filled> <if cond="answer"> <exit/> </if> <clear namelist="answer"/> </filled> </field> </form> </vxml>
この例の場合、アプリケーションはmain.vxmlが最初に読みこまれなければならないよう設計されている。そのapplication属性は、アプリケーションルートドキュメントとしてインポートされるapp-root.vxmlを指定する。よって、app-root.vxmlが読みこまれ、アプリケーション変数"bye"を生成し、また、ユーザが"オペレータ"と言うとoperator-xfer.vxmlに遷移するリンクを定義する。ユーザとの対話はsay_goodbyeと名づけられたformから始まる。
C:ちゃらにしましょうか
H:せやな
C:理解できませんでした。
(プラットフォームに依存する初期設定メッセージ)
H:ちゃら
C:理解できませんでした。
H:オペレータ
C:(operator_xfer.vxmlに移動し、人間のオペレータに転送する。)
マルチドキュメントアプリケーションの実行中は、同時に読み込まれるドキュメントは高々2つ:アプリケーションルートドキュメント、および、ユーザがルートドキュメントと対話していない場合はその他のアプリケーションドキュメント、であることに注意せよ。
もしドキュメントが、存在しないアプリケーションルートドキュメントを参照していたり、アプリケーションルートドキュメントが他のアプリケーションルートドキュメントを参照している場合は、error.semanticイベントが投げられる。
副対話
副対話は複雑な対話の系列をより良い構造にするために分割したり、再利用可能な部品を作成する機能である。例えば、口座情報の要求は、口座番号や電話番号のようないくつかの情報を集めることからなる。お客様相談サービスは、この基本的な構造を共有するいくつかの独立したアプリケーションから構成することができるので、この部分を副対話として構成することは妥当であろう。以下の例に示されている最初のドキュメントapp.vxmlは、適合する客の口座を捜索し、口座情報を獲得しそれから支払金額を得る。口座情報はユーザに入力を求める別のVoiceXMLドキュメントを呼び出す<subdialog>要素を用いて得ることができる。二番目のドキュメント(acct_info.vxml)が実行されている間、呼び出した側の対話は一時停止され、情報が戻ってくるのを待つ。二番目のドキュメントは<return>要素を使用してユーザとの会話の結果を提供し、結果の値は<subdialog>要素上でname属性により定義された変数を通してアクセスされる。
お客様サービスアプリケーション(app.vxml)
<?xml version="1.0"?> <vxml version="1.0"> <form id="billing_adjustment"> <var name="account_number"/> <var name="home_phone"/> <subdialog name="accountinfo" src="acct_info.vxml#basic"> <filled> <!-- 注:"accountinfo"によって定義された変数はECMAScriptの オブジェクトとして返され、"副対話"の"return"要素で指定 される変数によって定義される2つのプロパティを含む。 --> <assign name="account_number" expr="accountinfo.acctnum"/> <assign name="home_phone" expr="accountinfo.acctphone"/> </filled> </subdialog> <field name="adjustment_amount" type="currency"> <prompt> 支払金額はいくらですか? </prompt> <filled> <submit next="/cgi-bin/updateaccount"/> </filled> </field> </form> </vxml>
口座情報を収集するドキュメント(acct_info.vxml)
<?xml version="1.0"?> <vxml version="1.0"> <form id="basic"> <field name="acctnum" type="digits"> <prompt> 口座番号は何番ですか? </prompt> </field> <field name="acctphone" type="phone"> <prompt> 電話番号は何番ですか? </prompt> <filled> <!-- 2つのfieldによって得られた値は"return"要素によって呼び出した対話に戻る。 --> <return namelist="acctnum acctphone"/> </filled> </field> </form> </vxml>
副対話は、呼び出されたとき新しい実行環境を加える。副対話は既存のドキュメントの、または新しいドキュメントの内部で新しい対話になることができる。副対話を呼び出すと、アクティブな文法の有効範囲は副対話内に限られる。
図3にドキュメント(D)の系列が副対話(SD)に移り、戻るときの実行フローを示す。
formはVoiceXMLドキュメントの主要な要素である。
formは以下のものを含む。
formの属性:
id | formの名前 |
scope | formの文法のデフォルトでの有効範囲。属性値がdialogであれば、formの文法はそのフォーム内でのみアクティブである。属性値がdocumentであれば、formは同じドキュメント内の全ての対話の間でアクティブである。属性値がdocumentで、そのドキュメントがアプリケーションルートドキュメントなら、formの文法はこのアプリケーションの全てのドキュメント内の全ての対話の間でアクティブである。dialogをscopeの属性値として持つformの文法はそのフォームだけでアクティブである。 |
この節ではformのいくつかの概念について述べ、それからそれらの処理の詳細な例をあげる。
formは暗黙のフォーム処理アルゴリズム(FIA)により処理される。FIAのメインループではフォーム項目を選択して訪れることを繰り返す。選択されるフォーム項目は、ガード条件が満たされていない最初の項目である。フィールド項目のデフォルトのガード条件は、フィールド項目変数が値を持っていること、である。すなわちフィールド項目しか含まない単純なフォームであれば、ユーザは各フィールド項目について、順々に入力が促される。
フォーム項目の処理は一般的には次のようなものである:
移動のための制御命令を処理したときにはFIAは終了する。(例:<goto>による他の対話かドキュメントへの遷移、または<submit>によるドキュメントサーバへのデータの提供)またFIAは選択すべきフォーム項目が残っていないとき暗黙の<exit>により終了する。
フォームのフォーム項目はフォーム処理アルゴリズムのメインループ内で訪れられることのできる要素である。フィールド項目は指定されたフィールドの値の収集をFIAに指示する。FIAがコントロール項目を選択した場合、コントロール項目は実行可能な手続き型コードのブロックを含むか、混合主導型フォーム用の初期プロンプトを出力し、値の収集処理を初期化することをFIAに伝える。
フィールド項目はユーザから値を集めるためにフィールド項目変数を指定する。フィールド項目はユーザが何を言うべきか、または何をキー入力するべきかを教えるprompt、入力文を定義するgrammar、そして結果として生じるイベントを処理するイベントハンドラを持つ。フィールド項目はフィールド項目変数に値が代入された直後に行うべき行動を定義する<filled>要素を持つ。フィールド項目は次のものに細分される。
<field> | 音声認識またはDTMF文法によって値を得るフィールド項目。 |
<record> | ユーザにより録音されたオーディオクリップを値に持つフィールド項目。例えば、<record>要素はボイスメールメッセージを収集することができる。 |
<transfer> | ユーザを別の電話番号に転送するフィールド項目。もしその転送がコントロールを返してきたときは、フィールド変数はresult statusにセットされる。 |
<object> | このフィールド項目はさまざまなパラメータを持ったプラットフォーム依存"object"を呼び出す。プラットフォームオブジェクトの結果は、1つまたは複数のプロパティを伴うECMAScriptのオブジェクトである。あるプラットフォームオブジェクトは、クレジットカードの情報を収集する組み込み対話であるかもしれない。または、特有のDTMFテキスト入力方法を使用したテキストメッセージの収集を行うものかもしれない。 |
<subdialog> | <subdialog>フィールド項目は関数呼び出しのようなものである。処理中のページ上の他の対話や他のVoiceXMLドキュメントを呼び出す。その結果としてECMAScriptのオブジェクトを返す。 |
以下の2種類のコントロール項目が存在する。
<block> | プロンプトや計算に用いられる一連の手続き文であり、入力を集めるためには用いられない。実装命令文の集合。(非入力用) blockは処理される直前にtrueにセットされる(通常は暗黙の)フォーム項目変数を持っている。 |
<initial> | この要素は、混合主導型form内の最初の相互作用を制御する。そのプロンプトはフォームレベル文法に合致するユーザの発話を促すように記述されるべきである。<initial>要素の実行中に、少なくとも1つのフィールド項目変数が認識結果で満たされたとき、<initial>のフォーム項目変数はtrueになり、したがってFIAの選択肢から消去される。 |
それぞれのフォーム項目は関連したフォーム項目変数を持ち、formの処理に入ったときは、フィールド項目のフォーム項目変数はまた、フィールド項目変数とも呼ばれ、ユーザから入力された値を持つ。デフォルトでundefinedにセットされている。フォーム項目変数はフォーム項目の処理結果を値として持つ。フォーム項目変数はname属性を使用して名前が与えられるか、もしくは匿名のままにして、内部で生成した名前を持たせることができる。
それぞれのフォーム項目はフォーム処理アルゴリズムにより選択されるフォーム項目を制御するガード条件を持っている。デフォルトのガード条件はフォーム項目変数が値を持つかどうかを調べるものである。もし持ってるなら、そのフォーム項目は処理されない。
典型的には、フィールド項目は名前が与えられ、コントロール項目には与えられない。普通フォーム項目変数は初期値を与えられておらず、追加のガード条件も指定されていない。しかし時には、より詳細な制御をする必要がある。あるフォームはフィールドを隠すために値のセットされたフォーム項目変数を持っていて、その後フィールドによる入力を行うためにクリアされる。(例:<clear>の使用)他のフィールドはそのフィールドが満たされておらず、別の2つのフィールドが満たされた場合にのみアクティブになるガード条件を持っている。block項目は条件がtrueに保たれているときのみ実行することができる。従って、どの順序でフォーム項目を選択し実行するかに関して、FIAは詳細な制御が可能である。しかし概して、多くの対話はこのレベルの複雑さに頼ることなく、形成することができる。
要約すると、すべてのフォーム項目は次のような属性を持つ。
name | dialogスコープのフォーム項目変数の名前でフォーム項目の値を保持する。 |
expr | フォーム項目変数の初期値。デフォルトはECMAScriptのundefinedである。もしある値で初期化されると、フォーム項目変数はクリアされていない限り、フォーム項目は実行されない。 |
cond | 項目変数のテストを行うために評価する表現。もし存在しない場合、デフォルトはtrueであり、<initial>の場合は、いずれかのフィールド項目変数に値が埋められているかどうかのテストとなる。 |
最も単純で一般的な種類のフォームは、コンピュータによる指示的な相互作用を実現するためにフォーム項目が出現順に各々一度だけ実行されるものである。
以下にそのようなフォームを用いた天気情報サービスの例を示す。
<form id="weather_info"> <block> 天気情報サービスにようこそ。 </block> <field name="pref"> <prompt> 何県ですか? </prompt> <grammar src="pref.gram" type="application/x-jsgf"/> <catch event="help"> 天気を知りたい都道府県名を言ってください。 </catch> </field> <field name="city"> <prompt> 何市ですか? </prompt> <grammar src="city.gram" type="application/x-jsgf"/> <catch event="help"> 天気を知りたい都市の名前を言ってください。 </catch> </field> <block> <submit next="/servlet/weather" namelist="pref city"/> </block> </form>
対話は以下のように逐次的に進行する:
C(computer):天気情報サービスへようこそ。何県ですか?
H(human):ヘルプ
C:天気を知りたい都道府県名を言ってください。
H:京都府
C:何市ですか?
H:向日市
C:理解できませんでした。何市ですか?
H:京都市
C:午前11時の京都市の天気は快晴です...
最初の(暗黙の)フォーム項目変数の初期値はundefinedであるから、フォーム処理アルゴリズムの最初の繰り返しは1番目のblockを選択する。このblockはメインプロンプトを出力し、そのフォーム項目変数がtrueにセットされる。FIAの2番目の繰り返しで、最初のblockはフォーム項目変数が定義されているのでスキップされ、対話変数"pref"はundefinedであるので、"pref"フィールドが選択される。このフィールドはユーザにpref用の入力を促し、応答を変数"pref"にセットする。3回目のフォームの繰り返しは"city"フィールドの入力を促し、値を集める。4回目の繰り返しは最後のblockを実行し、別のURIに遷移する。
この例のそれぞれのフィールドは、返答を引き出すためのプロンプト、何を聞き取るか特定する文法、ヘルプイベント用のイベントハンドラを持っている。ヘルプイベントはユーザが補助を求めたときに投げ掛けられる。ヘルプイベントハンドラはこれらのイベントをキャッチし、さらに詳しいヒントを与える。
以下に指示的フォームの2つ目の例、クレジットカード情報入力を示す:
<form id="get_card_info"> <block> クレジットカードの種類、ナンバー、有効期限を入力します。 </block> <field name="card_type"> <prompt count="1"> クレジットカードの種類を入力してください。 </prompt> <prompt count="2"> カードの種類は? </prompt> <!-- this is an in line grammar --> <grammar> visa {visa} | master [card] {mastercard} | amex {amex} | american [express] {amex} </grammar> <help> Visa、Mastercard、American Expressのうちどれかをお持ちですか? </help> </field> <!-- type="digits"のgrammarが構築される --> <field name="card_num" type="digits"> <prompt count="1"> カード番号を入力してください。 </prompt> <prompt count="2"> カードの番号は? </prompt> <catch event="help"> <if cond="card_type == 'amex'"> 15桁の番号を音声かキーで入力して下さい。 <else/> 16桁の番号を音声かキーで入力して下さい。 </if> </catch> <filled> <if cond="card_type == 'amex' && card_num.length != 15"> American Expressのカード番号は15桁です。 <clear namelist="card_num"/> <throw event="nomatch"/> <elseif cond="card_type" != 'amex' && card_num.length !="16"/> Mastercard と Visaのカード番号は16桁です。 <clear namelist="card_num"/> <throw event="nomatch"/> </if> </filled> </field> <field name="expiry_date" type="digits"> <prompt count="1"> 有効期限を入力してください。 </prompt> <prompt count="2"> 有効期限はいつですか? </prompt> <help> 1201のように有効期限を音声またはキーで入力してください。 </help> <filled> <!-- validate the mmyy --> <var name="mm"/> <var name="i" expr="expiry_date.length"/> <if cond="i == 3"> <assign name="mm" expr="expiry_date.substring(0,1)"/> <elseif cond="i == 4"/> <assign name="mm" expr="expiry_date.substring(0,2)"/> </if> <if cond="mm == '' || mm < 1 || mm > 12"> <clear namelist="expiry_date"/> <throw event="nomatch"/> </if> </filled> </field> <field name="confirm" type="boolean"> <prompt> カードの種類 <value expr="card_type"/> 番号 <value expr="card_num"/> 有効期限 <value expr="expiry_date"/> です。 正しければ 「はい」 再入力するときは「いいえ」と言ってください。 </prompt> <filled> <if cond="confirm"> <submit next="place_order.asp" namelist="card_type card_num expiry_date"/> </if> <clear namelist="card_type card_num expiry_date acknowledge"/> </filled> </field> </form>
対話はこのように進められる:
C:クレジットカードの種類、ナンバー、有効期限を入力します。
C:クレジットカードの種類を入力してください。
H:Discover
C:理解できませんでした。(プラットフォームに依存する初期設定メッセージ)
C:カードの種類は? (2つめのpromptが使用されている)
H:シュート(幸運にもこのプラットフォームにより"ヘルプ"として扱われた)
C:Visa、Mastercard、American Expressのうちどれかをお持ちですか?
H:えー、Amexこのプラットフォームは「えー」を無視する)
C:カード番号を入力してください。
H:1 2 3 4 ....ちょっと待って...
C:理解できませんでした。
C:カード番号は?
H:123456789012345# (DTMFを使用)
C:有効期限を入力してください。
H:1 2 0 1
C:カードの種類Amex番号1234567890123456、満期の日は1201です。
正しければ「はい」再入力するときは「いいえ」と言ってください。
H:はい。
フィールドはformの主要な構成要素である。フィールドは変数を宣言し、プロンプト、文法、DTMFシーケンス、ヘルプメッセージ、そしてその他のイベントハンドラを特定する。それぞれのフィールドはそのformの対話スコープのVoiceXML field項目変数を宣言する。これらは一度formが満たされると、submitされたり、他の変数にコピーされる。
独自の音声入力文法かつ/またはDTMF文法を持ち、それぞれは<grammar>、<dtmf>を使って明示的に指示されるか、またはtype属性を用いて暗黙に指定される。type属性は標準組み込み文法(例:数字、真偽、番号など)を使用するために用いられる。type属性はまた、音声合成器がフィールドの値をどのように読むかを制御する。
それぞれのフィールドは1つまたはそれ以上のプロンプトを持つことができる。プロンプトを1つ持つ場合は、値が提供されるまで繰り返し用いられる。複数の場合、count属性を与えなければならない。これらはそれぞれの試行において使用するかを決定する。例ではプロンプトはだんだん短くなっている。これを先細リプロンプト(tapered prompting)と呼ぶ。
<catch event="help">要素は、ユーザがヘルプを要求した際に何をするかを定義したイベントハンドラである。ヘルプメッセージを次第に細くすることができる。
この要素は略記が可能であり、以下の2つの要素は等価である:
<catch event="help"> Visa、Mastercard、American Expressのうちどれかをお持ちですか? </catch> <help> Visa、Mastercard、American Expressのうちどれかをお持ちですか? </help>
<filled>要素は、ユーザがそのフィールドへの入力を提供したときに、何をするかを定義している。1つの用法としては、上記の例のデータフィールドにおいて、文法によりなされたチェックに加え、整合性制約を指定することである。
前の節ではコンピュータ主導の会話を実現するフォームについて詳しく述べた。フォームをコンピュータと人間のどちらでも会話の主導権をとれる混合主導型にするために、1つまたは複数の<initial>フォーム項目と1つまたは複数のフォームレベル文法が必要である。
もしフォームがフォームレベル文法を持っていると:
また、フォーム文法はユーザが他の対話にいるときにアクティブにすることができる。ドキュメントが例えばレンタカーフォームとホテル予約フォームのように2つのフォームを持っており、両方のフォームがそのドキュメントにおいて、アクティブである文法を持つと、ユーザはホテル予約情報入力の要求に対してレンタカーの情報を応答し、それによってコンピュータをレンタカーの話題へと導くことができる。ユーザは任意のアクティブな文法に対する入力ができ、フィールドに値をセットし、その応答行動をさせることができる。
例:以下に混合主導型を示した、天気予報サービスのversion 2を挙げる。広告そして都道府県と都市の確認とを持った実用目的の"付加価値バージョン"である。
<form id="weather_info"> <grammar src="cityandpref.gram" type="application/x-jsfg"/> <!-- 広告に割り込むことはできない --> <block> <prompt bargein="false"> 天気情報サービスへようこそ <audio src="http://www.online-ads.example/wis.wav"/> </prompt> </block> <initial name="start"> <prompt> どの県、都市の天気情報を希望しますか? </prompt> <help> 天気情報を希望する県と都市の名前を言って下さい。 </help> <!-- もしユーザが黙り込むと1度ヒントを与え、startに再度移行する --> <noinput count="1"> <reprompt/> </noinput> <noinput count="1"> <reprompt/> <assign name="start" expr="true"/> </noinput> </initial> <field name="pref"> <prompt> 何県ですか? </prompt> <help> 天気情報を希望する都道府県名を言って下さい。 </help> </field> <field name="city"> <prompt> 天気情報を希望する <value expr="pref"> 内の都市名を言って下さい。 </prompt> <help> 天気情報を希望する<value expr="pref">内の都市名を言って下さい。 </help> <filled> <!-- 客の大半は京都市にいる --> <if cond="city == '京都市' && pref == undefined"> <assign name="pref" expr="'京都府'"/> </if> </filled> </field> <field name="go_ahead" type="boolean" modal="true"> <prompt> <value expr="pref"/>,<value expr="city"/> でよろしいですか? </prompt> <filled> <if cond="go_ahead"> <prompt bargein="false"> <audio src="http://www.online-ads.example/wis2.wav"/> </prompt> </if> <clear namelist="start city pref go_ahead"/> </filled> </field> </form>
以下に初心者用でも使いやすくなった点を示した例をあげる:
C:天気予報情報サービスへようこそ。
ジョーのスパイシーシュリンプソースをよろしく。
C:天気情報を希望する県と都市の名前を言って下さい。
H:えー、京都府。
C:何市ですか?
H:舞鶴市。
C:京都府舞鶴市でよろしいですか?
H:いいえ。
C:何県ですか?
H:京都市。
C:京都府京都市でよろしいですか?
H:はい。
C:ジョーのスパイシーシュリンプソースを買うのを忘れないでね。
C:おおむね晴れが続き、夜半から下り坂です。
"go_ahead"フィールドは、trueにセットされたmodel属性を持つ。これは現在のフォーム項目内で定義されたもの以外のすべての文法を無効にするので、このフィールドでの唯一のアクティブな文法は"boolean"の組み込み文法である。
慣れたユーザはより早く情報を得ることができる。(しかし広告を飛ばすことはできない)
C:天気予報情報サービスへようこそ。
ジョーのスパイシーシュリンプソースをよろしく。
C:天気情報を..
H:京都市。
C:京都府京..
H:はい。
C:ジョーのスパイシーシュリンプソースを買うのを忘れないでね。
C:おおむね晴れが続き、夜半から下り坂です。...
フィールドの値の収集の順序制御
フォーム処理アルゴリズムはいくつかの方法でカスタマイズ可能である。1つの方法はそのフォーム項目が選択されないようにフォーム項目変数に値を割り当てる。別の方法としては、<clear>を使い、フォーム項目変数をundefinedにすることにより、強制的にFIAを再度フォーム項目に戻すという方法である。
他の方式は、<goto nextitem>を使い、次のフィールド項目を明示的に指定する方法である。これは、強制的にそのフィールド項目にただちに遷移する。もし<goto nextitem>が<filled>アクションの中で出現したとき、<filled>アクションの残りの部分と実行途中の<filled>アクションはスキップされる。
以下にexitイベントに応えて実行される<goto nextitem>の例を示す。
<form id="survey_2000_03_30"> <catch event="exit"> <goto nextitem="confirm_exit"/> </catch> <block> <prompt> もしもし、あなたは米国外交政策に重要な質問に答えるために無作為に選ばれました。 </prompt> </block> <field name="q1" type="boolean"> <prompt> Burkina Fasoの農務省の機能を民営化するIMFに同意しますか? </prompt> </field> <field name="q2" type="boolean"> <prompt> もし民営化するとOugadougouとBobo-Dioulassoに有益になるでしょうか? </prompt> </field> <field name="q3" type="boolean"> その結果モロコシとあわの出荷が1年当たり最大4%ほど増加するかもしれない のに同意するのですか? </prompt> </field> <block> <submit next="register" namelist="q1 q2 q3"/> </block> <field name="confirm_exit" type="boolean"> <prompt> exitを選びました。数十年間、米国外交政策のvis-a-vis sub-Saharan Africaに悪影響を及ぼしたいと確信しているのでしょうか? </prompt> <filled> <if cond="confirm_exit"> 分かりました。しかし米国国務省を怒らせます。 <exit/> <else> よろしいです。出ていきましょう。 <clear namelist="confirm_exit"/> </if> </filled> </field> </form>
もしユーザがある質問に対して"exit"と言うと、exitイベントがプラットフォームにより投げ掛けられ、<catch>イベントハンドラによりキャッチされる。このハンドラは"confirm_exit"が次に訪れるフィールドであると指定する。"confirm_exit"フィールドはアンケートが普通に終了していた場合はアクセスされることはない。なぜなら先の<block>要素が制御を登録スクリプトに移すからである。
フォーム処理アルゴリズム(FIA)について概念レベルでの説明は終了した。このセクションでは、フォーム処理アルゴリズムについて詳述する。
formの初期化は処理に入ったときに行われる。フォームの対話スコープのプロンプトカウンタ内部変数は1にリセットされる。各変数(フォームレベルの<var>要素とフォーム項目変数)は、undefinedまたはexpr属性の値に初期化される。
FIAのメインループは3つのフェーズからなる。
Selectフェーズ
遷移するための次のフォーム項目選択が目的。
Collectフェーズ
Collectフェーズの目的は入力かイベントの収集である。選択されたフォーム項目は参照され、フォーム項目の種類による行動を実行する。
Processフェーズ
Processフェーズの目的は、Collectフェーズで収集された入力かイベントの処理である。
Processフェーズの終了後、処理はSelectフェーズに戻ることにより継続する。より詳細なフォーム処理アルゴリズムは付録Cを参照のこと。
menuとは1つの無名フィールドを含むフォームのための簡易表現であり、ユーザに選択肢をプロンプトし、その選択に基づいて遷移を行うことができる。正規のフォームと同様にmenuは「ユーザが他の対話を実行するときにもアクティブである」というような文法の有効範囲を持つこともできる。
ユーザに三者択一させるmenuの例を示す。:
<menu> <prompt> ホームページへようこそ。 次のコンテンツから1つを選択してください: <enumerate/> </prompt> <choice next="http://www.sports.example/vxml/start.vxml"> スポーツ </choice> <choice next="http://www.weather.example/intro.vxml"> 天気 </choice> <choice next="http://www.stargazer.example/voice/astronews.vxml"> 天文学ニュース </choice> <noinput> 次のコンテンツから1つを選択してください: <enumerate/> </noinput> </menu>
対話の実行例:
C:ホームページへようこそ。次のコンテンツから1つを選択してください。
スポーツ;天気;天文学ニュース。
H:占星学
C:理解できませんでした。(プラットフォームに依存する初期設定メッセージ)
C:ホームページへようこそ。次のコンテンツから1つを選択してください。
スポーツ;天気;天文学ニュース。
H:スポーツ
C:(http://www.sports.example/vxml/start.vxmlに進む)
menu要素
menuの属性:
id | menuの識別子。<goto>か<submit>のターゲット。 |
scope | menuの文法の有効範囲。もしそれがdialog(デフォルト)なら、ユーザがmenuに遷移したときだけmenuの文法がアクティブになる。もしscopeがdocumentなら、その文法は全てのドキュメント上で有効である。(もしくは、もしmenuがアプリケーションルートドキュメント内にあるなら、アプリケーション内にドキュメントが読みこまれる。) |
dtmf | trueにセットするとき、明示的なDTMF要素を持たないchoiceには"1","2"などの暗黙DTMF要素が与えられる。 |
choice要素
<choice>要素はいくつかの選択肢を提供する。
choice属性:
dtmf | 選択用DTMFシーケンス。 |
next | 次の対話またはドキュメントのURI。 |
event | nextの指定の代わりに、投げ掛けられるイベントを指定する。 |
expr | nextの指定の代わりに、評価するためのexpressionを指定する。 |
caching | 12.1.参照 |
fetchaudio | 12.1.参照 |
fetchhint | 12.1.参照 これはdocumentfetchhintプロパティをデフォルトとする。 |
fetchitimeout | 12.1.参照 |
メニュー内のDTMF
menuは、純粋に音声またはDTMFのみを用いることもできるが、<menu>内に<property>要素を含めることにより両者を組み合わせることもできる。以下にchoiceのdtmf属性を用いて、DTMFのみでそれぞれのchoiceを与える明示的なシーケンスの例を示す。
<menu> <property name="inputmodes" value="dtmf"/> <prompt> スポーツは1、天気は2、天文学は3を押してください。 </prompt> <choice dtmf="1" next="http://www.sports.example/vxml/start.vxml"/> <choice dtmf="2" next="http://www.weather.example/intro.vxml"/> <choice dtmf="3" next="http://www.stargazer.example/voice/astronews.vxml"/> </menu>
他の方法として、<menu>のdtmf属性をtrueにセットすることにより、最初の9個のchoiceに連続なDTMF数値を割り当てることができる。
<menu dtmf="true"> <property name="inputmodes" value="dtmf"/> <prompt> スポーツは1、天気は2、天文学は3を押してください。 </prompt> <choice next="http://www.sports.example/vxml/start.vxml"/> <choice next="http://www.weather.example/intro.vxml"/> <choice next="http://www.stargazer.example/voice/astronews.vxml"/> </menu>
enumerate(列挙型)要素
<enumerate>(列挙型)要素は自動生成される選択肢の説明である。それはmenu内に出現する命令におけるそれぞれの選択に適するテンプレートを指定する。もしこの要素が何も内容を持たないとき、全ての使用されるchoiceを列挙するデフォルトテンプレートが処理コンテキストに使用される。もし内容を持つ場合、その内容はテンプレートを指定する。この指定は以下の2つの特別な変数を参照することができる。:
"_prompt"はchoiceのプロンプト、"_dtmf"はchoiceの割り当てられたDTMFシーケンスである。例えば、menuは次のように書き直すことができる。
<menu dtmf="true"> <prompt> ホームページへようこそ。 <enumerate> <value expr="_prompt"/> は <value expr="_dtmf"/> を、 </enumerate> 押してください。 </prompt> <choice next="http://www.sports.example/vxml/start.vxml"> スポーツ </choice> <choice next="http://www.weather.example/intro.html"> 天気 </choice> <choice next="http://www.stargazer.example/voice/astronews.vxml"> 天文学ニュース </choice> </menu>
動作:
C:ホームページへようこそ。スポーツは1を、天気は2を、天文学ニュースは3を、押してください。
<enumerate>要素は<option>要素のセットを含む<field>要素用のプロンプトと同様に使用される。(14.1.3.参照)
文法の生成
選択フレーズは認識すべき単語やフレーズのセットを指定する。ユーザは選択フレーズの単語列の部分集合からなるフレーズを言ってもよい。選択フレーズは<choice>要素内で直接または間接的に含まれる要素のPCDATAから構成される。例えば、プロンプト"Stargazer astrophysics news"に応じて、ユーザは"Stargazer","astrophysics","Stargazer news","astrophysics news"などと言ってよい。等価なJSGFルールは"[Stargazer] [astrophysics] [news]"となる。
以下に<choice>の下位要素を含んだPCDATAの使用の例をあげる。
<choice next="http://www.stargazer.example/voice/astronews.vxml"> <prompt> <audio src="http://www.stargazer.example/space.wav"> Stargazer <emp>astrophysics</emp> news </audio> </prompt> </choice>
このchoiceはオーディオファイルにより出力されるか、もしファイルが再生できないときは"Stargazer Astrophysics News"と出力される。choice用の文法は、<choice>の下位要素のPCDATAから集められた"[Stargazer][astrophysics][news]"と同値である。
処理モデル
menuは全ての仕事を1つのfieldで行うようなformのようにふるまう。menuプロンプト、menuイベントハンドラ、menu文法はそれぞれ、fieldプロンプト、fieldイベントハンドラ、menu文法に対応する。
処理に入ることで、menuの文法は生成、実行され、プロンプトが再生される。ユーザがchoiceにマッチした入力をするとき、制御の遷移は<choice>属性"next","expr","event"の値に従う(ただ1つの属性が指定できる)。
<link>要素は1つ以上の文法を持ち、それらの文法はすべて<link>要素を有効範囲とする。<link>内に含まれる文法は有効範囲を指定できない。入力がどれか1つの文法にマッチするとlinkはアクティブになる。そして以下のうち1つが実行される。
以下の例ではユーザが"本"と発話するか"2"キーを押すことでlinkがアクティブになる。
<link next="http://www.voicexml.org/books/main.vxml"> <grammar type="application/x-jsgf"> 本 | VoiceXMLの本 </grammar> <dtmf> 2 </dtmf> </link>
以下の例では、遷移先が現在のドキュメント内で動的に決定される。
<link expr="'#' + document.helpstate"> <grammar type="application/x-jsgf"> help </grammar> </link>
<link>要素は、<vxml>、<form>、またはフォーム項目の子になることができる。<vxml>階層にあるlinkはドキュメント全体を通じてアクティブである文法を持つ。<form>階層にあるlinkはユーザがformにいる間、アクティブである文法を持つ。もし、アプリケーションルートドキュメントがdocument階層のlinkを持つなら、その文法はどんなアプリケーションのドキュメントが実行されていてもアクティブである。
モーダルなフォーム項目を実行している時には、formまたはdocument階層にあるlink文法は非アクティブとなる。
linkは、新しいドキュメントに移動する代わりにイベントを投げるように定義することもできる。このイベントはlinkが指定した場所でなく、現在実行中の場所に投げる。例えば、ユーザの入力が以下のlinkの文法にマッチすれば、現在ユーザが訪れているフォーム項目にhelpイベントを投げる。
<link event="help"> <grammar type="application/x-jsgf"> arrgh | alas all is lost | fie ye froward machine | I don't get it </grammar> </link>
<link>の属性
next | URIへ移動。このURIはドキュメント、またはカレントドキュメント内の対話である。 |
expr | 与えられたECMAScript表現を評価することによりURIが動的に決定されることを除けば、nextと同じである。 |
event | ユーザが1つのlink文法に適合したときに投げるイベント。(注)next,exprまたはeventのどれか1つだけ指定できる。 |
caching | 12.1.参照 |
fetchaudio | 12.1.参照 |
fetchhint | 12.1.参照 デフォルトはdocumentfetchhintプロパティ。 |
fetchtimeout | 12.1.参照 |
VoiceXML変数はECMAScript変数と等価な関係にある。変数の命名規則はECMAScriptと同じである。ただしアンダスコア("_")で始まる名前は内部的に使用するために予約されている。
変数は<var>要素により宣言される。
<var name="home_phone"/> <var name="pi" expr="3.14159"/> <var name="city" expr="'Sacramento'"/>
フォーム項目により宣言することもできる。
<field name="num_tickets" type="number"> <prompt> チケットを何枚購入しますか? </prompt> </field>
明白な初期値を持たない変数はECMAScriptのundefined値に初期化される。変数は使用前に宣言されなければならない。
formにおいては、<var>により宣言される変数とフォーム項目によって宣言される変数は、formに入ったときに初期化される。初期化はドキュメント中の出現順序で行われることが保証される。よって以下の例は正しい:
<form id="test"> <var name="one" expr="1"/> <field name="two" expr="one+1" type="number"> </field> <var name="three" expr="two+1"> <field name="go_on" type="boolean"> <prompt> 「はい」か「いいえ」を言ってください。 </prompt> </field> <filled> <goto next="#tally"/> </filled> </form>
ユーザがこの<form>にアクセスすると、formの初期化は最初変数"one"を宣言し、その値を1にセットする。それからfield項目変数"two"を宣言し、それに2を与える。次に初期化ロジックは変数"three"を宣言し、数値3を与える。form処理アルゴリズムはその後メインループに入り、"go_on"フィールドの処理を始める。
変数は以下の有効範囲に対して宣言できる。
session | これらは読み出し専用の変数であり、ユーザセッション全体に関するものである。処理コンテキストにより宣言、セットされる。新しいセッション変数をVoiceXMLドキュメントで宣言することはできない。9.4.参照 |
application | アプリケーションルートドキュメント<vxml>の子要素である<var>要素によって宣言される。それらはアプリケーションルートドキュメントがロードされたときに初期化される。アプリケーションルートドキュメントがロードされている間これらの変数は存在し、ルートドキュメントおよびロード中のリーフ(葉)ドキュメントからアクセス可能である。 |
document | ドキュメント<vxml>の子要素である<var>要素で宣言される。ドキュメントがロードされたときに初期化される。ドキュメントがロードされている間存在しており、ドキュメント内からのみアクセス可能である。 |
dialog | 対話(<form>または<menu>)は、ユーザがその対話をアクセスしている間のみ有効な変数範囲を持ち、その対話の要素からアクセス可能である。対話における変数は<form>の子要素である<var>、実行可能内容(例:<block>内容またはcatch要素内容)に含まれる<var>要素、またはフォーム項目要素により宣言される。<form>要素の子要素<var>は、formが最初にアクセスされたときに初期化される。実行可能内容に含まれる<var>要素は、実行可能内容が実行されたときに初期化される。フォーム項目変数は、フォーム項目が収集されるときに初期化される。 |
(anonymous) | <block>、<filled>そしてcatch要素はそれぞれ変数範囲を匿名で定義し、その要素内で宣言された変数がこれに含まれる。 |
以下の図は変数範囲の階層を示している。
図中の白矢印は、それぞれの有効範囲そのものを名前として定義済みの変数を参照できることを示す。例えば、匿名、対話、そしてドキュメントの有効範囲において、ドキュメント有効範囲内の変数"X"は"document.X"として参照できる。
変数はcond、expr属性において参照できる。
<if cond="city == 'LA'"> <assign name="city" expr="'Los Angeles'"/> <elseif cond="city == 'Philly'"/> <assign name="city" expr="'Philadelphia'"/> <elseif cond="city == 'Constantinople'"/> <assign name="city" expr="'Istanbul'"/> </if> <assign name="var1" expr="var1 + 1"/> <if cond="i > 1"> <assign name="i" expr="i-1"/> </if>
condと、expr内で使われる表現の言語はECMAScriptそのものである。注:condの演算子">","<",">=","<=","&&"はXMLにおいてはエスケープされなければならない。(例:">","<")簡単のために、この文書の例ではXMLエスケープを用いていない。
変数の参照は、上述した変数範囲の階層に従って、内包している最も近い変数範囲とマッチする。変数範囲の名前を接頭辞に使うことで、変数参照を明確化したり不明瞭さを解決することができる。例:ドキュメント内で後に使用するために、フォーム項目変数の数値を保存する。
<assign name="document.ssn" expr="dialog.ssn"/>
もしアプリケーションルートドキュメントが変数xを持つならば、それは非ルートドキュメント内のapplication.x、そしてアプリケーションルートドキュメント内のapplication.xまたはdocument.xとして参照される。
session.telephone.ani | Automatic Number Identification。この変数は発信側の電話番号とともに電話着信を受信側に知らせるAutomatic Number Identificationサービスからの結果を提供する。この情報はサービスがサポートされている場合のみ提供され、さもなくばundefinedにされる。 |
session.telephone.dnis | Dialed Number Identification Service。この変数は発信者がかけた受信側の電話番号を指定するDialed Number Identification Serviceからの結果を提供する。この情報はサービスがサポートされている場合のみ提供され、さもなくばundefinedにされる。 |
session.telephone.iidigits | Information Indicator Digit。この変数は発信者の発信線(例:payphone,携帯電話,特別なオペレータハンドリング,prison)。Telecordiaは"Local Exchange Routing Guide"のそれぞれのvolumeの1章のII digitsの完全なリストを公開している。この情報はサービスがサポートされている場合のみ提供され、さもなくばundefinedにされる。 |
session.telephone.uui | User to User Information。この変数は発信者の共同加入線から設定を呼び出すISDNの一部としての補充情報を返す。この情報はサービスがサポートされている場合のみ提供され、さもなくばundefinedにされる。 |
<grammar>要素は以下のような音声入力文法を提供するために使われる。
<grammar>要素はこれら2つの要求仕様を満たすさまざまな文法フォーマットに適応できるように設計されている。現在VoiceXMLは文法フォーマットを指定せず、特定の文法フォーマットのサポートを要求しない(訳注:VoiceXMLの次期版ではXMLに基づく文法フォーマットが導入される予定。また、セマンティック情報の表現と処理のための標準規格が検討されている。)。これはVoiceXML用のオーディオファイルフォーマットや、一般的なHTML用のメディアフォーマットと同様である。
<grammar>要素はインライン(inline)文法か外部(external)文法を指定するために使われる。インライン文法は<grammar>要素の内容により指定される:
<grammar type="mime-type"> インライン音声入力文法 </grammar>
この場合、CDATAセクション内の内容は閉じている必要がある。inline文法用のtypeパラメータは<grammar>タグの内容を処理するために必要なMIMEタイプを指定する。
外部文法は次の形式により指定される:
<grammar src="URI" type="mime-type"/>
MIMEタイプは、URIプロトコル経由(HTTPの場合)での獲得時にファイル名の拡張子からこの情報が推論されるので、省略可能である。もしタイプが指定できないまたは推論できない場合、デフォルトタイプはプラットフォーム依存である。もしtype属性が指定されている場合、他の情報はオーバライドされる。
VoiceXMLとともにJava TM Speech API Grammar Format(JSGF)を使用する場合付録Dを参照せよ(注:JavaはSun Microsystems Inc.の登録商標。)。
<grammar>の属性:
src | external時の、文法の場所を指定するURI。 |
scope | "document"の場合、処理中のドキュメント(および適切なアプリケーションのリーフ(葉)ドキュメント)の全ての対話中でアクティブになる。"dialog"の場合、処理中のフォームの中でアクティブになる。省略された場合、文法の有効範囲は親要素により決定される。 |
type | 文法のMIMEタイプ。省略された場合、処理系が動的にタイプを決定しようと試みる。 |
caching | 12.1.参照 |
fetchhint | 12.1.参照 デフォルトはgrammarfetchhintプロパティ。 |
fetchtimeout | 12.1.参照 |
<dtmf>要素は以下のようなDTMF文法を指定するために使われる
(訳注:VoiceXMLの次期版では<dtmf>要素を廃止し<grammar mode="dtmf">と表記される予定。音声入力文法は<grammar mode="speech" >またはmode="voice")。
<dtmf>要素はこれら2つの要求仕様を満たすさまざまな文法フォーマットに適応できるように設計されている。
VoiceXMLは<grammar>と同じく特定の文法フォーマットのサポートを要求しない。広く普及するVoiceXML処理系が共通のフォーマットをサポートするように、標準化作業およびマーケティングが行われることを期待している。
<dtmf>要素は外部文法を以下のように記述するか、
<dtmf src="URI" type="mime-type"/>
またはインライン文法を参照することができる。
<dtmf type="mime-type"/> <!-- インライン DTMF 文法 --> </dtmf>
<dtmf>の属性は<grammar>の属性と同じである:
src | external時の、文法の場所を指定するURI。 |
scope | "document"の場合、処理中のドキュメント(および適切なアプリケーションのリーフ(葉)ドキュメント)の全ての対話中でアクティブになる。"dialog"の場合、処理中のフォームの中でアクティブになる。省略された場合、文法の有効範囲は親要素により決定される。 |
type | 文法のMIMEタイプ。省略された場合、処理系が動的にタイプを決定しようと試みる。 |
caching | 12.1.参照 |
fetchhint | 12.1.参照 デフォルトはgrammarfetchhintプロパティ。 |
fetchtimeout | 12.1.参照 |
field文法は常にそれらのfieldの有効範囲とされ、処理系がそのfieldを訪れるまでアクティブではない。field内に含まれる文法は有効範囲を指定できない。
link文法はlinkを含む要素を有効範囲とする。もしアプリケーションルートドキュメント内でこれが定義されている場合、linkはロードされている他のアプリケーションドキュメント内でもアクティブである。
form文法はデフォルトで対話を有効範囲としており、ユーザがそのformにいるときのみアクティブである。もし有効範囲としてdocumentが与えられるなら、それらはユーザがそのドキュメント内にいるときは常にアクティブである。もし有効範囲がdocumentで、そのドキュメントがアプリケーションルートドキュメントである場合、そのアプリケーション内の他のドキュメントを処理しているときにも常にアクティブである。form内の文法は、form要素の属性として有効範囲が指定されるか、あるいは<grammar>要素上の属性として有効範囲が指定されることにより、ドキュメントを有効範囲とする。もし両方が指定された場合、文法は<grammar>要素により指定された有効範囲を用いる。
menu文法もまた、デフォルトで対話を有効範囲としており、ユーザがそのmenuにいるときのみアクティブである。しかしdocumentを有効範囲として与えられると、ドキュメントを通してアクティブである。さらにそのドキュメントがアプリケーションルートドキュメントである場合は、そのアプリケーションに属するすべてのドキュメント内でアクティブである。menuのchoice要素内に含まれる文法には有効範囲を指定できない。
formはしばしば、ドキュメントを通じてアクティブな文法をいくつか持ち、form内でのみアクティブな文法をいくつか持つ必要がある。1つの理由は文法のオーバラップの問題を最小化するためである。この目的で、有効範囲が<form>要素の有効範囲と異なる場合、個々の<grammar>と<dtmf>要素は独自の有効範囲を持つことができる:
<form scope="document"> <grammar> ... </grammar> <grammar scope="dialog"> ... </grammar> </form>
処理系があるフィールドの入力を待っているとき、以下の文法がアクティブとなる。
もしフォーム項目がモーダル(modal属性がtrue)ならば、そのフォーム項目以外の全ての文法は入力待ちの間、無効にされる。現在処理中のもの以外のフォームまたはメニューの文法に入力がマッチした場合は、制御は別のフォームまたはメニューに移る。入力によって処理中のフォームを去る場合には、処理中のフォームにおけるすべてのデータは失われる。
プラットフォームは、ユーザが応答しない場合、明瞭に返答しない場合、ヘルプを要求した場合、などにイベントを投げる。VoiceXML処理系は、VoiceXMLドキュメント内の意味的な誤りを発見した場合、<throw>要素に遭遇した場合にイベントを投げる。イベントは文字列により識別される。
ある要素の中でイベントが起こりうる場合、その要素は以下のようなキャッチ要素を持つ。
ある1つの要素は、必要に応じて、その上位の要素からキャッチ要素を(コピーされたように)継承する。
例えばもし1つのfield要素がnomatchのためのキャッチ要素を含まず、上位のform要素がnomatchを含むならば、そのform要素のnomatchが用いられる。この方法で、共通のイベントハンドリングの振る舞いはすべてのレベルで指定可能であり、それはすべての下位要素に適用される。
<throw>要素はイベントを投げる。いくつかのイベントはあらかじめ定義されている。
<throw event="nomatch"/> <throw event="telephone.disconnect.hangup"/>
またはアプリケーションで定義されたイベントも使用できる。
<throw event="com.att.portal.machine"/>
<throw>の属性
event | 投げられるイベント名 |
catch要素はキャッチ処理をドキュメント、対話またはフォーム項目と結び付ける。catch要素は実行可能内容を含む(訳注:<catch>の中で同じイベントをthrowすると無限ループに陥る(VoiceXML 2.0 Working Draft)。)。
<form id="launch_missiles"> <field name="password"> <prompt> コード単語は何ですか? </prompt> <grammar> カブハボタン </grammar> <help> それはあいまいな野菜の名前です。 </help> <catch event="nomatch noinput" count="3"> <prompt> セキュリティ違反! </prompt> <submit next="apprehend_felon" namelist="user_id"/> </catch> </field> <block> <goto next="#get_city"/> </block> </form>
<catch>要素の属性
event | catchの対象となる1つまたは複数のイベント(訳注:イベントは空白区切りリスト。複数のイベントのそれぞれのためにcount属性を管理すべき(VoiceXML 2.0 Working Draft))。 |
count | イベントの発生回数(デフォルト値は1)。countにより同じイベントを回数ごとに異なる方法で処理できる。フォーム項目と<menu>は処理されている間イベント発生数カウンタを維持する;これらのカウンタは<menu>またはフォーム項目の<form>の処理に入り直すときにリセットされる。 |
cond | イベントをこの要素でキャッチすべきかどうかを指定するためのオプション条件。デフォルトは真(true)。 |
<error>, <help>, <noinput>および<nomatch>要素は、<catch>要素のよく使用される形式のための略記法である。
<error>要素は<catch event="error">の省略であり、error型のすべてのイベントをキャッチする。
<error> エラーが発生しました -- 後ほど電話してください。 <exit/> </error>
<help>要素は<catch event="help">の省略である。
<help> ヘルプは用意されていません。 </help>
<noinput>要素は<catch event="noinput">の省略である。
<noinput>聞き取れませんでした。もう一度入力してください。</noinput>
<nomatch>要素は<catch event="nomatch">の省略である。
<nomatch>入力がありましたが、知らない都市でした。</nomatch>
これらの要素は次のような属性を持つ。
count | イベントの発生回数。(<catch>と同様) |
cond | イベントをこの要素でキャッチすべきかどうかを指定するためのオプション条件(<catch>と同様)。デフォルトは真(true)。 |
ある1つの要素は、必要に応じて、その上位の要素からキャッチ要素を(コピーされたように)継承する。
イベントが投げられるとき、イベントが処理される有効範囲と、その有効範囲を内包する上位の有効範囲について、最適なキャッチ要素が選択される。そのアルゴリズムは以下の通りである:
投げられたイベントの名前が正確に一致するか、あるいは接頭辞が一致していれば、投げられたイベントはキャッチ要素とマッチすると見なされる。catch要素のevent属性が投げられるイベントの名前と共通の接頭辞を持つ場合に接頭辞が一致したと見なされる。例えば、
<catch event="telephone.disconnect">
これはtelephone.disconnect.transferイベントと接頭辞が一致する。
アプリケーションの作者がnoinput, help, nomatch, cancel, exitおよびerrorイベントのハンドラを指定しない場合は、VoiceXML処理系が暗黙のデフォルトのハンドラを提供することが期待されている。
さまざまなイベントやエラーのためのハンドラのデフォルトの処理は、(1)音声応答を提供する必要があるか、(2)どの程度実行に影響するか、に応じて下記の表のように定義される。注:音声レスポンスが提供される場合、その内容はプラットフォーム依存である。
イベントタイプ | 音声応答 | アクション |
---|---|---|
cancel | no | repromptしない |
error | yes | 処理系からexit |
exit | no | 処理系からexit |
help | yes | repromptする |
noinput | no | repromptする |
nomatch | yes | repromptする |
telephone.disconnect | no | 処理系からexit |
allother | yes | 処理系からexit |
特定のプラットフォームとlocaleによって、デフォルトのプロンプトは異なる。
イベントにはあらかじめ定義済みのイベントとアプリケーション定義のイベントがある。イベントはまた、通常イベント(通常発生)とエラーイベント(異常発生)に細分される。エラーの命名規約は複数のレベルが許される。
定義済みのイベント
cancel | ユーザが再生中のプロンプトのキャンセルを要求した。 |
telephone.disconnect.hangup | ユーザが回線をハングアップした。 |
telephone.disconnect.transfer | ユーザが別の回線へ転送され制御が戻らない。 |
exit | ユーザがexitを要求した。 |
help | ユーザがヘルプを要求した。 |
noinput | ユーザが制限時間内に応答しなかった。 |
nomatch | ユーザが何かを入力したが、認識できなかった。 |
定義済みのエラー:
error.badfetch | フェッチの失敗。ドキュメントが存在しない場合、URI入力ミス、ドキュメントフェッチ処理中の通信エラー、タイムアウト、セキュリティ違反、または不正なドキュメント、などによる。 |
error.semantic | ランタイムエラーがVoiceXMLドキュメントで起きた。例:0除算、サブストリング境界エラー、または未定義変数の参照。 |
error.noauthorization | ユーザがリクエストした操作を実行する権限をもたない。(無効な電話番号にダイヤルした、またはユーザが電話をかけることを許可されていない。) |
error.unsupported.format | リクエストされたリソースがプラットフォームによりサポートされていない。例:サポートされていない文法フォーマット、オーディオファイルフォーマット、オブジェクトタイプまたはMIMEタイプ。 |
error.unsupported.element | プラットフォームが要素elementをサポートしていない。例えば、もしプラットフォームが<record>を実装しないなら、error.unsupported.recordを投げなければならない。これにより開発者は、さまざまなプラットフォームの能力に対応できる。 |
アプリケーション依存エラータイプは以下の形式に従うべきである:
error.com.mot.mix.noauth | 個人情報へのアクセスする権限を持たない。 |
error.com.ibm.portal.restricted | 制限されたリソースへのアクセスをドキュメントが試みた。 |
catchは特定のイベント(cancel)または、接頭辞(error.unsupported)を共有するすべてのイベントをキャッチできる。
URIの内容のフェッチングによって以下のことがVoiceXML処理コンテキストで起きる:(1)処理のためのVoiceXMLドキュメントをフェッチする、あるいは、(2)オーディオファイル、オブジェクト、文法、スクリプトのような他のドキュメントタイプをフェッチする。フェッチング処理の詳細は以下の3つの属性によって決定される。
caching | 内容の最新コピーを常に強制的にフェッチするか、もしそれがエクスパイアしてなかった場合に内容のキャッシュ済みコピーを使用するかを決める。指定がない場合、最も内側のcachingプロパティが用いられる。 |
fetchtimeout | error.badfetchイベントを投げるまで、内容が返るのを待つ時間。指定がない場合、最も内側のfetchtimeoutプロパティが用いられる。 |
fetchhint | 処理コンテキストがサーバから内容をいつ取得すべきかを定義する。prefetchはそのページがロードされたときファイルをダウンロードしてもよいことを示す。これに対してsafeは、実際に必要となった時点でのみダウンロードを許す。大容量のファイル(長時間のダウンロードを要する)またはオーディオソースをストリームする場合、streamにより内容すべての取得を待たないで処理コンテキストが内容の処理を始められる。指定がない場合、最も内側の*fetchhintプロパティの値が用いられる。 |
URIから内容がフェッチされる場合、caching属性は取得する場所(キャッシュを用いるか否か)を決定する。fetchtimeout属性は内容を待つ時間の長さ(リソースが必要とされた時点から計測する)を決定する。fetchhintはいつ内容をフェッチするかを決定する。VoiceXML処理コンテキストのキャッシングの方針は次のセクションで詳説する。
fetchhint属性はいつ内容をフェッチすることができるかを示し、これによって処理コンテキストの処理性能を高めることを助ける。処理コンテキストは実際にはsafeセッティング以外の方針でドキュメントをフェッチするとき、異なる処理を行う必要はない。しかしprefetchまたはstreamセッティングで処理に対応した処理コンテキストであっても、safeセッティングでの処理もできなくてはならない。
ある対話から別の対話へ遷移するとき、<subdialog>, <goto>, <submit>, <link>,または<choice>要素においては、処理系の振る舞いに影響する追加ルールがある。もし参照されたURIがドキュメント名に対話名をつけたものである(例:"doc#dialog")か、またはクエリーデータが提供されている(POSTまたはGETを通して)なら、新しいドキュメントが取得される(ローカルキャッシュまたはサーバから)。新しいドキュメントが取得された場合、そのドキュメントはその初期化フェーズ(例:必要ならば新しいアプリケーションルートドキュメントの取得、初期化、ドキュメント変数の初期化、そしてドキュメントスクリプトの実行)を通過する。要求された対話(指定されない場合は最初の対話)は、その後で初期化され、対話の実行が始まる。もし参照されたURIが対話名だけの場合(例:"#dialog")、ドキュメントは新たには取得されず、ドキュメントの初期化も実行されない。要求された対話は引き続いて処理される。
VoiceXMLドキュメントをフェッチする要素は以下の追加属性もサポートする:
fetchaudio | フェッチの間再生されるオーディオクリップのURI。指定されない場合は、fetchaudioプロパティが使用され、もしプロパティがセットされていないなら、フェッチの間オーディオは再生されない。 |
fetchaudio属性は次のドキュメントの取得中に目立つ遅延がある場合、ユーザの好感度を高めるのに有用である。これは、BGMの再生またはアナウンスの連続再生に使用できる。ドキュメントの取得が完了した場合に、再生が続いていれば、そのオーディオファイルは中断される。
VoiceXML処理コンテキストは、ちょうどHTMLビジュアルブラウザのように、ドキュメントのフェッチングやその他のリソースにおいてパフォーマンスを向上するためにキャッシュを使用することができる;VoiceXMLドキュメントでのオーディオファイルはHTMLにおける画像と同様である。ビジュアルブラウザでは、最新でないと判断される内容のアップデートやリフレッシュの制御をエンドユーザも行うことができた。VoiceXML処理コンテキストの場合これとは違い、その後同等のエンドユーザコントロールが必要である。従って、キャッシュリフレッシュの実行は、VoiceXML処理コンテキストにより使用されるキャッシングの方針の特定の使用を通した随意のアプリケーションプログラムである。
VoiceXML処理コンテキストのデフォルトのcaching policyはHTMLブラウザ内で共通に使われるそれである。:
VoiceXMLではこのcaching policyは高速と知られている。しかし高速なキャッシュ使用法は異例な結果をロードすることができる為、VoiceXML処理コンテキストもまたsafe caching policyを実装する:
safe caching policyは、パフォーマンス(ドキュメントサーバへの余分なアクセスによる)を犠牲にして、VoiceXML処理コンテキストがいつもドキュメントの最新バージョンを持つことを確実にする。safe policyはHTMLビジュアルブラウザ内でいつも再読みこみまたはリフレッシュするWebページの影響と同様である。
VoiceXMLは作者にどちらのcaching policyを使用するか選択することを許している。確かな要素のcaching属性はその要素のために使用するデフォルトpolicyを決定するためにsafeかfastにセットされるべきである。もし属性が特定されないならば、policyはcachingプロパティの数値を特定する<property>要素により決定される。(17章参照)
例:
<?xml version="1.0"?> <vxml version="1.0"> <!-- このドキュメント内の要素はデフォルトで caching="fast" を使用する --> <property name="caching" value="fast"/> ... <form id="test"> <block> <!-- Welcomeは滅多に変更されないので fast cachingが良い --> <audio src="http://www.weather4U.example/vxml/welcome.wav"/> <!-- Adsは常に変わるので、safe cachingが必要である --> <audio caching="safe" src="http://www.onlineads.example/weather4U/ad17"/> </block> ... </form> ... </vxml>
開発、ドキュメントとリソースが絶え間なく変更されているとき、そしてシステムテストとその後の製作に入るアプリケーションとして"safely"フェッチされたリソースとともにfast cachingを使用する間、safe cachingが使用されることは習慣である。
おそらくまずないが、デフォルトでsafe cachingを使用し、fast caching policyを使用するいくつかのリソースをフェッチする生産アプリケーションを持つことも可能である。
prompt要素は音声合成と録音音声の出力を制御する。
概念上、プロンプトは再生用の待ち行列に即時に追加されるので、ユーザの入力が必要になるまで処理が進められる。その後プロンプトが再生され、システムはユーザの入力を待つ。音声認識サブシステム(またはDTMF認識装置)から入力を受け取ると、処理は続行する。
promptは以下の属性を持つ:
bargein | ユーザがプロンプトを中断できるかどうかを制御する。デフォルトは真(true)。 |
cond | プロンプトが有効かどうかを指示する式。デフォルトは真(true)。 |
count | もしユーザが繰り返し何かをするとき、毎回異なるプロンプトを再生することを許すための値。省かれた場合は、デフォルトで1になる。 |
timeout | ユーザ入力のために使用されるタイムアウト値。デフォルトのnoinputタイムアウトはプラットフォーム依存である。 |
プロンプトの例は以前に示した:
<prompt> 住んでる都市を言ってください。 </prompt>
もし以下のとき、<prompt> ... </prompt>は省略できる:
例えば、これらもプロンプトである:
住んでいる都市を言ってください。 <audio src="say_your_city.wav"/>
しかし音声マークアップを埋め込む場合には、<prompt> ~ </prompt>をプロンプトから省くことはできない:
<prompt> 住んでいる都市を<emp>言って</emp>ください。 </prompt>
prompt要素はemphasis、break、prosodyを示すためのマークアップを含むことができる(訳注:VoiceXMLの次期版ではW3C Speech Synthesys Markup Languageが定義される予定である。)。
<prompt> これ<emp>も</emp>コンピュータによって生成された文章です。 <break size="medium"/> 気に入りましたか? </prompt>
VoiceXMLは以下の音声マークアップ要素をサポートしている。
音声出力の休止(pause)の指定。
<break>の属性:
msecs | 休止時間(単位はm秒) |
size | 相対的な休止時間。取りうる値:none、small、medium、large |
msecs(訳注:VoiceXMLの次期版ではmsecstimeとなる予定。)とsizeの高々1つが指定されなければならない。もし指定されないなら、size="medium"が割り当てられる。
内包するテキストの種類を示す(訳注:VoiceXMLの次期版では<paragraph>および<sentence>という表記も導入される予定。)。
<div>の属性:
type | 取りうる値は | sentenceまたはparagraphである。 |
内包されたテキストを強調して話すべきであることを指定する。
<emp>の属性:
level | 強調のレベルを指定する。取りうる値は:strong、moderate(デフォルト)、none、reduced |
内包されたテキストの韻律(prosody)情報の指定。属性の値のフォーマットについての詳細は、Java API Speech Markup Language specification (v0.5-1997年8月27日)(訳注:VoiceXMLの次期版ではW3C Speech Synthesys Markup Language specification)を参照のこと。
<pros>の属性:
rate | 話速の指定 |
vol | 出力音量の指定 |
pitch | ピッチの指定 |
range | ピッチ範囲の指定 |
単語やフレーズがどのように読み上げられるべきかを指定する。
<sayas>の属性:
phon | テキスト内容の代替としてUnicode International Phonetic Alphabet(IPA)文字による表現 |
sub | テキスト内容の代替として読み上げるテキストの定義 |
class | とりうる値は、phone、data、digits、literal、currency、number、time |
しばしばテキストは特定のスタイルを用いて表現される必要がある。例えば、北米電話番号プランに準拠した電話番号では、最初の3桁、次の3桁の後に休止が必要である。これを行うためにclass属性を用いる。:
<prompt> あなたは<value expr="home_num" class="phone"/>に電話しました。 </prompt> <prompt> あなたは<sayas class="phone">312-555-1212</sayas>に電話しました。 </prompt>
処理系は音声マークアップのフルセットを扱う必要がある。しかし、実装プラットフォームが同じレベルの音声マークアップ機能を持たない音声合成エンジンを使用している場合は、プラットフォームは可能な限りVoiceXMLのマークアップを対応付けする必要があるだろう。全てのプラットフォームで全ての音声マークアップ要素の使用が認められるべきであり、もし特定のマークアップ要素がサポートされていなくても、テキスト内容の読み上げは行われなくてはならない。
プロンプトでは合成音声によるオーディオクリップを用いることが可能である。
<prompt> Bird Seed Emporiumへようこそ。 <audio src="http://www.birdsounds.example/thrush.wav"/> 今月はアザミの種250kgが <sayas class="currency">299.95ドル</sayas> に郵送料と手数料がかかります。 <audio src="http://www.birdsounds.example/mourningdove.wav"/> </prompt>
音声はどのプロンプトにおいても再生可能である。通常はURI経由で指定されるが、録音済みのaudio変数を使用することもできる。
<prompt> 録音したメッセージは次のとおりです。 <value expr="greeting"/> 保存するには1を押してください。 続けるには2を押してください。 メインメニューに戻るにはシャープを押してください。 終わるには米印を押してください。 </prompt>
audioタグ要素はオーディオサンプルが利用できない場合、代替テキスト(マークアップを含む)を用いることができる。:
<prompt> <audio src="welcome.wav"> <emp>ようこそ</emp> 音声ポータルへ。 </audio> </prompt>
オーディオファイルが再生できない場合(例:フォーマットの未サポートや無効なURIなど)は、audio要素の内容が代わりに読み上げられる。この内容はテキスト、音声マークアップ、または他のaudio要素を含む。もしオーディオファイルが再生できず、audio要素の内容が空(empty)であれば、対応するerrorイベントが投げられる。
<audio>の属性:
プロンプトには<value>要素を使い変数参照を埋め込むことができる。:
<prompt> あなたは<value expr="home_num"/>に電話しました。 </prompt>
<value>の属性:
expr | 引き渡すための表現。 |
class | 変数の<sayas> class、例:phone、date、currency。妥当なフォーマットは<sayas>音声マークアップ内でサポートされているそれと同じである。 |
mode | レンダリング(rendering)形式。tts(デフォルト)またはrecorded |
recsrc | modeがrecordedのときのオーディオファイルのURI。 |
もし実装プラットフォームがバージイン(barge-in)をサポートするなら、サービス制作者はユーザがプロンプトに割り込みさせること(プロンプトに"バージイン"させること)を許すかどうか指定できる。これは対話をスピードアップさせるが、常に望まれているわけではない。もしユーザが警告、法律の注意、または広告の全てを聞かなければならないなら、barge-in実行不可能であるべきである。これはbargein属性により行われる:
<prompt bargein="false"><audio src="legaless.wav"/></prompt>
ユーザは、bargein属性が真(true)であるプロンプトに割り込み可能であるが、bargein属性が偽(false)であるプロンプトではユーザは終了を待たなければならない。いくつかのプロンプトが並んでいる場合、それぞれのプロンプトのbargein属性はそのプロンプトの再生中それぞれ使用される。シーケンス内の一つのプロンプトにバージインされた場合はすべての後続プロンプトが再生されなくなる。bargein属性が指定されていない場合は、bargeinプロパティの値が使用される。
先細りプロンプト(tapered prompt)は試行回数に応じて変更されるプロンプトである。情報要求(Information-requesting)プロンプトは、ユーザがタスクにより精通しているようになるという仮定の下でより簡潔になるべきである。ヘルプメッセージは、おそらくユーザがさらにヘルプを必要とするという仮定の下でより詳しくなるべきである。または、プロンプトは相互作用をより興味深くするためだけに変更できる。
それぞれのフォーム項目とmenuは、そのformまたはmenuに入ったそれぞれのときにリセットされる内部プロンプトカウンタを持っている。システムがプロンプトを使用しているときはいつも、その関連したプロンプトカウンタはインクリメントされる。これが先細りプロンプトをサポートするためのメカニズムである。
例えばformレベルのプロンプトと、fieldレベルのプロンプトをもつformの例を挙げる。
<form id="tapered"> <block> <prompt bargein="false">アイスクリームsurveyへようこそ。</prompt> </block> <field name="flavor"> <grammar>バニラ|チョコレート|ストロベリー</grammar> <prompt count="1">何にしますか?</prompt> <prompt count="3"> バニラ、チョコレート、ストロベリーから選んでください。 </prompt> <help>申し訳ありませんが、ヘルプは用意されていません。</help> </field> </form>
以下にこのformを使用した会話を示す。:
C:アイスクリームsurveyへようこそ
C:何にしますか? ("flavor"fieldのプロンプトカウンタ= 1)
H:ピカンプラーリーン
C:理解できませんでした。
C:何にしますか? (プロンプトカウンタ= 2)
H:ピカンプラーリーン
C:理解できませんでした。
C:バニラ、チョコレート、ストロベリーから選んでください。(プロンプトカウンタ= 3)
H:それらが嫌ならどうなりますか?
C:理解できませんでした。
C:バニラ、チョコレート、ストロベリーから選んでください。(プロンプトカウンタ= 4)
H:....
プロンプトを選択するときにはプロンプトカウンタとの比較が行われる。count属性の値がプロンプトカウンタより少ないか一致するもので、count属性の値が最大であるような子promptが使用される。もしpromptがcount属性を持たないなら、"1"が初期設定される。
条件付きプロンプト)conditional prompt)は、条件が満たされているとき使用される。以下の例では、フォームを訪れるたびにプロンプトが変更される:
<form id="another_joke"> <var name="r" expr="Math.random()"/> <field name="another" type="boolean"> <prompt cond="R < .50"> 他の象の冗談を聞きたいですか? </prompt> <prompt cond="r >= .50"> 他の冗談を聞きたければ「はい」と、聞きたくなければ「いいえ」と言ってください。 </prompt> <filled> <if cond="another"> <goto next="#pick_joke"/> </if> </filled> </field> </form>
プロンプトの選択において、待ち行列に追加されるプロンプトの集合は以下のアルゴリズムにより選択される:
こうしてリストに残ったすべての要素が、再生のために待ち行列に追加される。
timeout属性は、最後のプロンプトが終わったあと、ユーザ入力を待つことが許される沈黙のインターバルを指定する。もしこのインターバルを上回ると、プラットフォームはnoinputイベントを投げ掛ける。この属性のデフォルト数値はtimeoutプロパティで指定される。(17章参照)
プロンプトの属性としてtimeoutを許す理由は、tapered timeoutをサポートするためである。例えば、ユーザが最初の入力を試みるために5秒、次にすすむのに10秒を与えてもよい。
プロンプトにおけるtimeout属性は、以降の入力でのnoinput timeoutの値を決定する。
<prompt count="1"> 新しいT型の色を選んでください。 </prompt> <prompt count="2" timeout="120s"> 新しい1920年式T型フォードの色を選んでください。 可能な色は黒か黒か黒です。時間をとってください。 </prompt>
もし、いつくかのプロンプトがfield入力の前に待ち行列されているなら、最後のプロンプトのtimeoutが使用される。
フォーム項目はform処理中に訪れることのできる<form>内の要素である。それらは、<field>、<block>、<initial>、<subdialog>、<object>、<record>、<transfer>が含まれる。全てのフォーム項目が以下の特徴を持っている。
それぞれのフィールド項目は関連したシャドウ変数(shadow variable)のセットを持ちうる。シャドウ変数はフィールド項目の実行からの結果を返すために使われ、他の変数はname属性以下に記憶させておく。例えば、それは<field>要素内で認識された文法の結果をもたらされたconfidence levelを知るのに便利である。シャドウ変数は、フィールド項目のname属性の変数であるnameの場所name$.shadowvarとして、そして指定シャドウ変数の名前であるshadowvarとして参照される。例えば、<field>要素はシャドウ変数confidenceを返す。以下にコード断片はどのようにshadow変数がアクセスされるかを示す。
<field name="state"> <prompt> 状態名を言ってください。 </prompt> <grammar src="http://mygrammars.example/states.gram"/> <filled> <if cond="state$.confidence < 0.4"> <throw event="nomatch"/> </if> </filled> </field>
この例では、結果のconfidenceが調べられ、もしconfidenceが小さいなら結果がリジェクトされる。
fieldはユーザから収集されるための入力項目を指定する。fieldの属性は以下のものを含む。:
name | 結果を保持する対話スコープ内のfield項目変数 |
expr | フォーム項目変数の初期値;デフォルトはECMAScript undefinedである。もし変数が初期化されているなら、そのフォーム項目はフォーム項目変数がクリアされなければ訪れられることはない。 |
cond | フォーム項目が訪れられるために真(true)と評価されなければならないboolean condition |
type | fieldのタイプ。例:内部文法の名前。この名前はすべての準拠プラットフォームによりサポートされる標準セットからならなければならない。もし存在しない場合、<grammar>かつ/または<dtmf>要素が代わりに指定されることができる。 |
slot | 変数を実装するために使われる文法スロットの名前(もし存在しないなら、変数名がデフォルトとなる)。この属性は、スロット/変数のセットを返す為のメカニズムを持ち、スロット名がfield項目変数名と違う、使用されている文法フォーマットで便利である。もし文法が、ブール代数のように組み込み式文法を返すときただ1つのスロットを返すなら、どんなスロット名でもfield項目変数はそのスロットの値を得る。 |
modal | もしこれがfalse(デフォルト)なら、このフィールドの値を収集している間、全てのアクティブな文法も有効である。もしこれがtrueなら、フィールド文法のみが有効ある:すべての他の文法は一時的に無効になる。 |
名前がnameである<field>要素のシャドウ変数:
name$.confidence | 認識結果内の0.0-1.0のconfidence level。0.0は最小confidenceをさし、1.0は最高confidenceをさす。confidence数値の処理のさらなる指定はプラットフォーム次第である。 |
name$.utterance | 認識された単語そのままの文字列。正確なtokenizationと綴りはプラットフォーム指定(例:"five hundred thirty"または"5 hundred 30"または"530")である。 |
name$.inputmode | ユーザ入力が提供されるモード(dtmfかvoice) |
<field>タイプ属性は本質的な組み込み文法を指定するためにつかわれ、もしその後プロンプト内の数値属性内で使用されるなら、どのようにその数値が話されるかをも特定する。例えば:
<field name="lo_fat_meal" type="boolean"> <prompt> フライト中、低脂肪な食事がよろしいですか? </prompt> <help> 低脂肪な食事は脂肪が10g以下で250cal以下です。 </help> <filled> <prompt><emp><value expr="lo_fat_meal"/></emp> ですね。</prompt> </filled> </field>
この例において、booleanタイプは、入力は真(true)または偽(false)のどちらかの形式であることを指す。実際にfieldに代入される数値はtrueかfalseのどちらかである。fieldはプロンプト内で「はい」または「いいえ」と読まれる。
次の例で、digitは、入力が話されたまたはキー入力された数字列であることを指す。結果は文字列として保持され、数字として表現される。例:"百二十三"ではなく、"一-二-三"。<filled>アクションは、fieldが12桁の数字かどうかを検出する。もし違えば、ユーザにエラーメッセージを聞かせ、repromptによりnomatchイベントが投げ掛けられる。
<field name="ticket_num" type="digits"> <prompt> チケットから12桁の数字を読んでください。 </prompt> <help> 12桁の数字は左下にあります。 </help> <filled> <if cond="ticket_num.length != 12"> <prompt> 申し訳ございませんが、聞き取れませんでした。 </prompt> <assign name="ticket_num" expr="undefined"/> </if> </filled> </field>
それぞれの組み込みタイプ用の入力規約があることが重要である。例えば、汎用のプロンプトおよびヘルプのメッセージを、VoiceXMLの全ての実装に対応できるように記述することができる。これらはロケール依存であり、若干の差異が許されている。例えば、booleanタイプの文法は「はい」「いいえ」と返事することを最小限許されているが、実装において「うん」のような別の選択を加えることは自由である。この場合、アプリケーションは異なった振る舞いを要する場合、明示的にフィールド文法を使うべきである。
それに加え、組み込みタイプには返された数値のフォーマット用の規約がある。組み込みfield用のreturnタイプは、boolean fieldタイプ用以外の文字列である。実際の認識結果にアクセスするために、作者はシャドウ変数name$.utteranceを参照することができる。
すべての組み込みタイプは音声とDTMF入力の両方をサポートしなければならない。
組み込みタイプ:
boolean | 入力は、カレントlocaleに適当な断定的そして否定的なフレーズを含む。DTMF1が「はい」そして2が「いいえ」。結果はECMAScript trueが「はい」またはfalseが「いいえ」である。数値は文字列"true"または"false"として渡される。もしfield数値が後にprompt内で使用されるなら、カレントlocaleに適切な断定的または否定的フレーズとして話される。 |
date | 有効な音声入力は年月日を情報として持つ日付の指定するフレーズを含む。DTMF入力:4桁の西暦、それにつづき2桁の月、さらに2桁の日。結果はフォーマット"yyyymmdd"である固定長データ文字列である。例:20000704。もし、西暦が指定されないなら、yyyyは"????"として返される。;月、日も同様にmm、ddは"??"として返される。 |
digits | 有効な音声またはDTMF入力は1桁またはそれ以上の0?9の数字列を含む。結果は数字の文字列である。もしfield数値がその後prompt内で使用されるなら、数字の羅列で話される。ユーザは例えば「二千百二十七」でなく、「二一二七」と言うことができる。 |
currency | 有効な音声入力は流通貨幣を指定するフレーズを含む。DTMF入力では、小数点の代わりに"*"キーを活用すればよい。結果はフォーマットが"UUUmm.mm"である文字列であり、UUUにはISO標準4217:1995またはもしユーザにより話されないならNULLによる3文字の通貨インジケータが入る。もしfield数値が後でprompt内で使用されるなら、その場に応じた通貨として話される。 |
number | 有効な音声入力は「百二十三」または「5.3」のような数を指定するフレーズを含む。有効なDTMF入力は、数字と小数点の代わりに"*"を用いて入力する数を含む。結果は0から9の数字と、オプションとして小数点(".")と/またはプラス・マイナスの記号を含む文字列である。 |
phone | 有効な音声入力は電話番号を指定するフレーズを含む。DTMFアスタリスク"*"は"x"を意味する。結果は数字と拡張付き電話番号を指すための文字"x"からなる電話番号を含む文字列である。北アメリカ対応で、結果は"80055512345x789"となる。 |
time | 有効な音声入力は時間と分を含む時間を指定するためのフレーズを含む。結果はフォーマット"hhmmx"となる5文字の文字列であり、xは"a"でAM、"p"でPM、"h"で24時間時計を用いて時間を指し、"?"で曖昧に時間を指す。DTMFを通して入力が可能である。なぜならDTMF入力の場合、AM/PMを特定するための規約がなく、結果は常に"h"または"?"で終わる。もしfieldの値が後でprompt内で使用されるなら、数値はその場において適当な時間として話される。 |
明示文法は絶対パスまたは相対パスによるURIを通して指定されることが可能である。
<field name="flavor"> <prompt> 何にしますか? </prompt> <grammar src="../grammar/ice_cream.gram" type="application/x-jsgf"/> </field>
文法は内部で指定されることが可能である、例えばJSGFを用いる。:
<field name="flavor"> <prompt> 何にしますか? </prompt> <help> バニラ、チョコレート、ストロベリーから選んでください。 </help> <grammar type="application/x-jsgf"> バニラ {van} | チョコレート {choc} | ストロベリー {straw} </grammar> <dtmf type="application/x-jsgf"> 1 {van} | 2 {choc} | 3 {straw} </dtmf> </field>
選択肢の単純なセットが全てfieldへの規定通りの入力数値を指定する必要があるなら、オプションリストを文法よりも使いやすくするべきである。オプションリストは、<field>要素に含まれる<option>要素により表示される。それぞれの<option>要素は、<choice>に記述される同じ秩序を使用することを受諾する音声入力用の文法を生成するために使用されるPCDATAを含む。それは、オプションの選択とオプションが選択されたとき、数値をfieldに渡すためのDTMFキーを指定する属性をも持つ。
以下のfieldはユーザに3つの選択肢を投げ掛け、maincourse変数へ選択されたオプションのvalue属性の数値を受け渡す。
<form> <field name="maincourse"> <prompt> メインディッシュを選んでください。今日のメニューは <enumerate/> です。 </prompt> <option dtmf="1" value="fish"> メカジキ </option> <option dtmf="2" value="beef"> ローストビーフ </option> <option dtmf="3" value="chicken"> カエルの足 </option> <filled> <submit next="/cgi-bin/maincourse.cgi" method="post" namelist="maincourse"/> </filled> </field> </form>
この会話は以下のように行われる。:
C:メインディッシュを選んでください。今日のメニューはメカジキ;ローストビーフ;
カエルの足です。
H:カエルの足
C:("maincourse"に"chicken"を渡し、その後/maincourse.cgiへ"maincourse=chicken"を提出。)
<enumerate>要素については7章で説明している。
<option>の属性:
dtmf | このオプション用のDTMFシーケンス |
value | ユーザがこのオプションを音声またはDTMFにより選択したときに、field項目変数に受け渡す文字列。この属性のデフォルト数値は、行間隔と削除された後書きスペース付きの<option>要素のCDATA文書である。 |
いくつかの組み込みfieldタイプはパラメータ化できる。これは、特別-目的"builtin:"URIスキーマと<grammar>または<dtmf>要素のsrc属性の、またはfieldのtype属性のformtype?parm=valueのURIスタイル問い合わせ構文を使用する組み込み文法を明示的に参照することにより行われる。例えば:
<grammar src="builtin:grammar/boolean"/> <dtmf src="builtin:dtmf/boolean?y=7"/> <field type="digits?minlength=3;maxlength=5">....</field>
定義により、
<field type="X">...</field>
と
<field> <grammar src=builtin:grammar/X"/> <dtmf src="builton:dtmf/X"/> .... </field>
は、Xが1つの組み込みfieldタイプ(boolean,date,etc.)である点で同様である。digitsとboolean文法は以下のようにパラメータ化される。:
digits?minlength=n | 最低n桁の数字列 |
digits?maxlength=n | 最高n桁の数字列 |
digits?length=n | 厳密にn桁の数字列 |
boolean?y=d | 肯定の答えとしてdキーを押すとみなすDTMF文法 |
boolean?n=d | 否定の答えとしてdキーを押すとみなすDTMF文法 |
注:1つ以上のパラメータは上記の説明のように";"により分けて指定される。<grammar>または<dtmf>要素内の、src属性URIは上記のようにbuiltin:grammar/またはbuiltin:dtmfにより始めなければならない。
<grammar>要素が<field>要素内で指定されるとき、それはfieldのtype属性により暗示されるデフォルト会話文法を上書きする。同様に、<dtmf>要素が<field>要素内で指定されるとき、それはデフォルトDTMF文法を上書きする。
blockはフォーム項目である。それは、もしblockのフォーム項目変数がundefinedであり、blockのcond属性が少しでもtrueと評価するなら実行可能内容を含む。
<block> Flamingo.exampleへようこそ、your source for lawn ornaments. </block>
フォーム項目変数はそのblockに入る丁度前に自動的にtrue(真)にセットされる。その点では、blockはformの起動毎にただ1度、典型的に実行される。
時々、block上でさらに制御が必要となる。このため、フォーム項目変数に名前をつけることと、<block>の実行を制御するためにその変数をセットまたはクリアすることが可能である。この変数はformのdialog scope内で定義される。
<block>の属性:
name | 実行することが適当なブロックを追跡するために使用されるフォーム項目変数;デフォルトではアクセスできない内部変数である。 |
expr | フォーム項目変数の初期値;デフォルトはECMAScriptにおけるundefined値である。もしある値で初期化されるなら、そのフォーム項目はクリアされない限り訪れられない。 |
cond | 訪れられるフォーム項目にとって適切にtrue(真)を評価しなければならないブール型コンディション。 |
典型的な混合主導型form内で、<initial>要素はユーザが最初にform-wide情報をプロンプトされたとき訪れられ、そしてそれぞれのfieldが単一で要請される指示モード内部にまだ入っていない。field項目のように、それはprompt、catch、そしてeventカウンタを持っている。field項目との相違点は、<initial>は文法と<filled>アクションを持たないことである。例えば:
<form id="get_from_and_to_cities"> <grammar src="http://www.directions.example/grammars/from_to.gram"/> <block> 電話によるドライブ案内へようこそ。 </block> <initial name="bypass_init"> <prompt> どこからどこへ行きたいですか? </prompt> <nomatch count="1"> Atlanta GeorgiaからToledo Ohioのように言ってください。 </nomatch> <nomatch count="2"> 申し訳ございません、理解できませんでした。 情報の一部分をたずねます。 <assign name="bypass_init" expr="true"/> <reprompt/> </nomatch> </initial> <field name="from_city"> <grammar src="http://www.directions.exaple/grammars/city.gram"/> <prompt> 出発地はどこですか? </prompt> ... etc. ... </field> ... etc. ... </form>
<initial>要素にアクセスしている間、全てのフィールド文法が非アクティブである。もし<initial>が訪れられている間にイベントが発生したら、イベントハンドラが実行される。他のフォーム項目と同様、<initial>はフォーム項目変数がundefinedでありcond属性がtrueである間、訪れられる。もし1つ以上のフィールド項目変数がユーザ入力によりセットされたら、すべての<initial>のフォーム項目変数は、<filled>アクションが実行される前にtrueにセットされる。
<initial>フォーム項目変数は不可能であることを明示的にごまかすこと、または<initial>のFIAを再度可能にする。例えば、上のプログラム内で、<initial>のフォーム項目変数が2回目のnomatchイベントにセットされる。このもはや<initial>と見なさないため、かつ次のフォーム項目を選択するためのFIAの目的は、初めのcityのために明確にpromptするための<field>である。同様に、<initial>のフォーム項目変数はクリアされることができるので、<initial>はFIAにより再選択されることが可能になる。
注:field項目変数への明確な数値の受け渡しは<initial>のフォーム項目変数の数値に影響を与えない。
<initial>の属性:
name | <initial>が実行するのに適しているかどうかをトラックするために使用されるフォーム項目変数の名前;デフォルトは得難い内部変数 |
expr | フォーム項目変数の初期値;デフォルトはECMAScript undefinedである。もし数値を初期化するなら、フォーム項目はフォーム項目変数がクリアされるまでアクセスされることはない。 |
cond | フォーム項目にアクセスするためにはtrueに評価されていなければならないブール型コンディション。 |
<subdialog>要素はそのsrc属性により指定される"called"dialog(subdialogとして知られている)を含む。subdialogは新しい実行コンテキスト内で実行する。subdialogは、subdialogから返る原因となる<return>要素の実行まで続けられる。subdialogが返るとき、その実行文書は削除され、実行はいくつかの特定の<filled>要素とともに呼び出すdialog内で再起する。1つの実行文書はすべての宣言と対話、対話のドキュメント、そして(存在する場合)アプリケーションルート用の状態情報をインクルードする。subdialogは、クレジットカード情報のユーザへのプロンプティング、または再利用可能アプリケーションのライブラリの構築の例のような共通対話の再利用の許可ができる。
subdialogの属性:
name | subdialogから返された結果で、プロパティが<return>要素のnamelist属性内で定義されているECMAScriptオブジェクト。 |
expr | フォーム項目変数の初期値。デフォルトはECMAScript undefinedである。もし数値が初期化されたなら、フォーム項目はフォーム項目変数がクリアされるまでアクセスされることはない。 |
cond | アクセスされているフォーム項目がtrueかどうかを評価するブール型のコンディション。 |
modal | subdialog間で、アクティブである文法を制御する。もしtrue(デフォルト)なら、全ての文法が実行不能呼び出し対話内でアクティブである。 |
namelist | デフォルトで何も渡さない点を除き、<submit>内のnamelistと同等である。他のドキュメントをフェッチするときに限って有効である。 |
src | <subdialog>のURI |
method | 19.8参照 |
enctype | 19.8参照 |
caching | 12.1.参照 |
fetchaudio | 12.1.参照 |
fetchtimeout | 12.1.参照 |
fetchhint | 12.1.参照 |
<subdialog>要素は全てのフォーム項目に共通の要素を含み、<param>要素をも含む。<param>要素はsubdialogへ渡すためのパラメータを指定する。これらのパラメータは<var>要素を用いsubdialog内で定義される;フォーム項目変数もしくは<param>要素を用いた未定義変数のセットを試みることは構文エラーである。subdialogが初期化される際、その変数がexpr属性を持たない場合、<param>要素に一致するよう初期化される。従って、<param>要素はexpr属性なしで<var>要素を初期化することだけができる。
以下の例では、個人の誕生日が運転免許証を検証するために使われている。subdialogのsrc属性は同一ドキュメント内のformを参照している。<param>要素はsubdialogへのパスのために誕生日の数値が使われている。
<!-- subdialogを呼び出すform dialog --> <form> <subdialog name="result" src="#getdriverslicense"> <param name="birthday" expr="'2000-02-10'"/> <filled> <submit next="http://myservice.example/cgi-bin/process/"/> </filled> </subdialog> </form> <!-- 運転免許証情報をsubdialogが得る --> <form id="getdriverslicense"> <var name="birthday"/> <field name="drivelicense"> <grammar src="http://grammarlib/drivegrammar.gram" type="application/x-jsgf"/> <prompt> 運転免許証を言ってください。</prompt> <filled> <if cond="validdrivelicense(drivelicense,birthday)"> <var name="status" expr="true"/> <else/> <var name="status" expr="false"/> </if> <return namelist="drivelicense status"/> </filled> </field> </form>
driver's licenseの値は、免許が正当かそうでないかを示すためのステータス変数と一緒に対話呼び出しへ返される。
以下の例もまたサーバサイドスクリプティングの使用抜きでsubdialog内の数値を具体化するための手段としてsubdialogへデータを受け渡す手段としての<param>の使用の便利さを示している。スクリプティングを使用する替わりのソリューションを以下に示す。
subdialogを呼び出すformのあるドキュメント
<?xml version="1.0"> <vxml version="1.0"> <form> <field name="birthday" type="date"> 誕生日はいつですか? </field> <subdialog name="result" src="/cgi-bin/getlib#getdriverslicense" namelist="birthday"> <filled> <submit next="http://myservice.example/cgi-bin/process"/> </filled> </subdialog> </form> </vxml>
subdialogを含むドキュメント(/cgi-bib/getlibによって生成された)
<?xml version="1.0"?> <vxml version="1.0"> <form id="getdriverlicense"> <var name="birthday" expr="'1980-02-10'"/> <!-- サーバースクリプトにより生成された --> <field name="drivelicense"> <grammar src="http://grammarlib/drivergrammar.gram" type="application/x-jsgf"/> <prompt> 運転免許証番号を言ってください。</prompt> <filled> <if cond="validdrivelicense(drivelicense,birthday)"> <var name="status" expr="true"/> <else/> <var name="status" expr="false"/> </if> <return namelist="drivelicense status"/> </filled> </field> </form> </vxml>
上記の例では、サーバサイドスクリプトはドキュメントを生成し、誕生日の値を埋め込まなくてはいけない。
subdialogが処理されるとき、アクティブな文法のみがsubdialogのdialog-有効範囲内のそれらでありかつデフォルト文法が処理コンテキストにより定義される(例:help,cancel)。アクティブ文法のセットは<return>が実行されるまで、限られたすべての後続の対話が残る。例えば、もしsubdialogAが対話Bへうつるなら、Bの処理はその対話スコープとデフォルト文法内のアクティブな文法のみを検討する。
以下の例は、クレジットカード情報全般を取り込むためのsubdialogを示す。最初のsubdialogは、複数のドキュメント内で定義されている。;それは異なるアプリケーションを通して再利用可能であることを意味する。それはステータス、クレジットカード番号、そして満了日を返す;もし結果が獲得できないなら、ステータスとして値"no_result"を返す。
<?xml version="1.0"?> <vxml version="1.0"> <!-- クレジットカード情報を収集するsubdialogの例 --> <!-- ファイルは http://www.somedomain.example/ccn.vxmlにある --> <form id="getcredit"> <var name="status" expr="'no_result'"/> <var name="username"/> <field name="creditcardnum"> <prompt> クレジットカード番号は何番ですか? </prompt> <help> クレジットカード情報を収集しています。 <reprompt/> </help> <nomatch> <return namelist="status'/> </nomatch> <grammar .../> </field> <field name="expirydate" type="date"> <prompt> クレジットカードの有効期限はいつですか? </prompt> <help> クレジットカードの有効期限を収集しています。 <reprompt/> </help> <nomatch> <return namelist="status"/> </nomatch> </field> <block> <assign name="status" expr="'result'"/> <return namelist="status creditcardnum expirydate"/> </block> </form> </vxml>
呼び出し関数を含むアプリケーションを以下に示す。ソフトウェア製品の名前と混合主導型対話を使用するオペレーティングシステムを獲得し、それからsubdialogを用いクレジットカード情報を要請する。
<?xml version="1.0"?> <vxml version="1.0"> <!-- メインプログラムの例 --> <!-- http://www.somedomain.example/main.vxml --> <!-- subdialog ccn.vxml を呼び出す --> <var name="username"/> <!-- いくつかの対話によって定義されると仮定する --> <form id="buysoftware"> <var name="ccn"/> <var name="exp"/> <grammar .../> <initial name="start"> <prompt> 購入するソフトウェアとそのソフトウェアが動作するOSを言ってください。 </prompt> <noinput> <assign name="start" expr="true"/> </noinput> </initial> <field name="product"> <prompt> どのソフトウェアを購入したいですか? </prompt> </field> <field name="operatingsystem"> <prompt> このソフトウエアはどのOSで動作しますか? </prompt> </field> <subdialog name="cc_results" src="http://somedomain.example/ccn.vxml"> <filled> <if cond="cc_results.status=='no_result'"> 申し訳ございません、クレジットカード情報を得られませんでした。 この注文はキャンセルされます。 <exit/> <else/> <assign name="ccn" expr="cc_results.creditcardnum"/> <assign name="exp" expr="cc_results.expirydate"/> </if> </filled> </subdialog> <block> 注文を受け付けました。お待ちください。 <submit namelist="username product operatingsystem ccn exp"/> </block> </form> </vxml>
VoiceXML実装プラットフォームはspeaker verification、native components、additional telephony functionalityなどのようなアプリケーションが使用したいプラットフォーム指定機能を持つ。そのようなプラットフォーム指定オブジェクトは、HTML <OBJECT>要素に類似の<object>要素を使用することによりアクセスされる。例えば、nativeクレジットカード収集オブジェクトはこのようにアクセスされることができる。
<object name="debit" classid="method://credit_card/gather_and_debit" data="http://www.recordings.example/prompts/credit/jesse.jar"/> <param name="amount" expr="document.amt"/> <param name="vendor" expr="vendor_num"/> </object>
この例で、<param>要素は呼び出されるときに、オブジェクトにパスするためのパラメータとして使われる。この<object>は実行されるとき、そのフォーム項目変数の値としてECMAScriptオブジェクトを返す。この<block>はクレジットカードオブジェクトから返された数値を渡す。
<block> <prompt> カードの種類は <value expr="debit.card"/> です。 </prompt> <prompt> カード番号は <value expr="debit.card_no"/> です。 </prompt> <prompt> 有効期限は <value expr="debit.expiry_date"/> です。 </prompt> <prompt> 認証コードは <value expr="debit.approval_code"/> です。 </prompt> <prompt> 確認番号は <value expr="debit.conf_no"/> です。 </prompt> </block>
他の例として、プラットフォームが電話のキーを利用して任意のテキストメッセージの入力をユーザに許す機能を持っていると仮定する。
<form id="gather_pager_message"> <object name="message" classid="builtin://keypad_text_input"> <prompt> 1文字につき1回キーボードを押すことによりメッセージを入力して ください。スペースはスターを入力して下さい。メッセージを終了 するにはポンドサインを押してください。 </prompt> </object> <block> <assign name="document.pager_message" expr="message.text"/> <goto next="#confirm_pager_message"/> </block> </form>
ユーザは最初pager messageのためにプロンプトされる、それからキー入力する。<block>はメッセージを変数document.messageにコピーする。
<object>の属性:
name | objectが評価されるとき、objectにより定義されるECMAScript数値のタイプにこの変数をセットする。 |
expr | フォーム項目変数の初期値;デフォルトはECMAScript undefined。もし数値が初期化されるなら、フォーム項目はフォーム項目変数がクリアされるまで訪れられることはない。 |
cond | フォーム項目に訪れるために、trueと評価する必要があるブール型のコンディション。 |
classid | オブジェクトの実装の場所を指定するURI。URI規約はプラットフォーム依存である。 |
codebase | classid、data、archiveにより指定されるURIを決定するために使用されるベースパス。デフォルトはカレントドキュメントのベースURI。 |
codetype | classidにより指定されたオブジェクトをダウンロードしているとき、期待されるデータの内容(content)タイプ。指定されていない場合、デフォルトでtype属性の数値があてがわれる。 |
data | objectのデータの場所を指すURI。もしそれが適切なURIなら、codebase属性に関連のある処理をする。 |
type | data属性により指定されるデータのコンテンツタイプ。 |
archive | classidとdata属性により指定されるリソースを含むリソースに関連するオブジェクトを含むアーカイブに格納するためのURIのspace-separatedリスト。 |
caching | 12.1.参照 |
fetchaudio | 12.1.参照 |
fetchhint | 12.1.参照 デフォルトはobjectfetchhintプロパティ。 |
fetchtimeout | 12.1.参照 |
もし<object>要素が未知のobjectを参照するなら、error.unsupported.objectイベントが投げ掛けられる。プラットフォーム-指定オブジェクトを提供するための実装への要求はないが、<object>要素のサポートは要求される。
<record>要素はユーザからの録音を集めるfield項目である。録音はfield項目変数に格納され、再生またはサーバへの受け渡しが可能である。以下に例を示す。:
<?xml version="1.0"?> <vxml version="1.0"> <form> <record name="greeting" beep="true" maxtime="10s" finalsilence="4000ms" dtmfterm="true" type="audio/wav"> <prompt> 音がしたら、挨拶してください。 </prompt> <noinput> 聞き取れませんでした。もう一度お願いします。 </noinput> </record> <field name="confirm" type="boolean"> <prompt> あなたの挨拶は <value expr="greeting"/> です。 </prompt> <prompt> これでよろしければ「はい」と、 よくなければ「いいえ」と言ってください。 </prompt> <filled> <if cond="confirm"> <submit next="save_greeting.pl" method="post" namelist="greeting"/> </if> <clear/> </filled> </field> </form> </vxml>
ユーザは挨拶のためにプロンプトされ、挨拶を録音する。挨拶は再生され、もしユーザが気に入れば、HTTP POST methodで記憶用のサーバ上に送られる。他のfield項目と同様に、<record>はpromptとcatch要素を持つ。<filled>アクションも持つであろう。もしプラットフォームが同時の認識・録音をサポートしているなら、formと文法を有効範囲とするドキュメントは録音が進行している間はアクティブであることができる。
<record>の属性:
name | 録音を保持するfield項目変数。 |
expr | フォーム項目変数の初期値;デフォルトはECMAScript undefined。もし数値が初期化されるなら、フォーム項目はフォーム項目変数がクリアされるまで訪れられない。 |
cond | 訪れられるためにフォーム項目がtrueと評価されなければならないブール型条件。 |
modal | もしこれがtrue(デフォルト)なら、すべての上位レベルの音声入力とDTMF文法は録音中は止められる。 |
beep | もしtrueなら、録音する直前に音が発せられる。デフォルトはfalse。 |
maxtime | 録音の最高継続時間。 |
finalsilence | 対話の終了を示す、無音時間。 |
dtmfterm | もしtrueなら、DTMFキー入力で録音を終了する、デフォルトはtrueである。DTMFトーンは録音部分ではない。 |
type | 録音結果のMIMEフォーマット。デフォルトはプラットフォーム指定フォーマット。 |
<record>shadow変数name$は、録音終了後以下のECMAScriptプロパティを持つ。
name$.duration | 録音時間。単位はm秒 |
name$.size | 録音音声のサイズ。単位はbyte |
name$.termchar | もしdtmfterm属性がtrueかつ、ユーザがDTMFキー入力により録音を終了したなら、このshadow変数は入力されたキーである。(例:"#")他の場合はnullである。 |
時々、ユーザと処理系の間のセッションを一時停止し、別の構成要素とともにセッションを始めることが適当である。多くのカレントプラクティス内のこの能力にとって共通の使用は、電話会話中のユーザを、処理系を用い電話ネットワークを通してサードパーティにつなげることである。<transfer>要素は処理系にサードパーティコネクションのようなものを形成することを指示する。2つのシナリオがサポートされている:
bridging | 処理系による、発信者のセッション再開。 |
blind transfer | 再開不能;通話が接続されると同時にプラットフォームがtelephone.disconnect.transferを投げる。 |
そのフォーム項目変数は試転送の結果を格納するために使用される。以下は可能な数値である。
busy | 終端点がコールを拒んだ。 |
noanswer | 指定された時間内に返事がない。 |
network_busy | 中間ネットワークがコールを拒んだ。 |
near_end_disconnect | コールが成功し、発信者により切断された。 |
far_end_disconnect | コールが成功し、着信者により切断された。 |
network_disconnect | コールが成功し、ネットワークにより切断された。 |
この例はユーザがお客様サポートセンターに移動することを試み、それから会話が終了するのを待っている。:
<form name="transfer"> <var name="myfur" expr="0"/> <block> <audio src="chopin12.wav"> </block> <transfer name="mycall" dest="phone://18005551234" connecttimeout="30s" bridge="true"> <filled> <assign name="mydur" expr="mycall$.duration"/> <if cond="mycall == 'busy'"> <prompt> 申し訳ございません、お客様センターは他のお客様への仕事で 忙しいです。後ほど試みてください。 other customers. Please try again later. </prompt> <elseif cond="mycall == 'noanswer'"/> <prompt> 申し訳ございません、お客様サポートセンターの営業時間は 月曜日から土曜日の午前9時から午後7時までです。 </prompt> </if> </filled> </transfer> <block> <submit namelist="mycall mydur" next="/cgi-bin/report"/> </block> </form>
bridge転送の間、プラットフォームは発信者からのDTMF入力を察知することができる。特に、もしDTMF文法が<transfer>要素内部に存在するなら、文法にマッチするDTMF入力によって転送を切断し、処理系へ制御を返す。bridge転送はenclosed<grammar>要素にマッチする発生の認識により切断される。<transfer>要素はそのアクティブである有効範囲の外部に定義されている文法がないmodalである。
属性:
name | 転送を試みた結果。 |
expr | フォーム項目変数の初期値。;デフォルトでECMAScript undefinedである。数値が初期化されるなら、フォーム項目変数がクリアされるまで、フォーム項目が訪れられることはない。 |
cond | フォーム項目が訪れられるためには、trueでないといけないブール型コンディション。 |
dest | 受信者のURI(電話番号、IP telephony address) |
destexpr | 受信者のURIを渡すECMAScript表現 |
bridge | この属性はコールが繋がったときに何をするか決定する。もしbridgeがtrueなら、ドキュメント処理はコール切断が転送されるまで停止する。 |
connecttimeout | noanswerコンディションが返還される前に電話をつなごうとしている間の待ち時間。デフォルトはプラットフォーム指定である。 |
maxtime | 電話が継続することを許される時間。もし任意の時間続けることができるなら、0とする。 |
<transfer>隠れ変数(name$)は、転送完了後以下のECMAScriptプロパティを持つ。
name$.duration | コールが成功するまでの継続時間。単位は秒(浮動小数点数) |
<transfer>内で投げ掛けるイベント。
telephone.disconnect.hangup | 発信者がハングアップした場合。 |
telephone.disconnect.transfer | もし発信者が無条件に別の回線に移され、戻れない場合。 |
<filled>要素は、いくつかのフィールドの値がユーザ入力によって埋められたときに実行するアクションを指定する。<form>要素の子として、もしくはフィールド項目の子として使用可能である。<form>要素の子としては、<filled>要素は1つまたは複数のfieldが満たされたときアクションを実行するために使用できる。例えば、以下の<filled>要素はend_cityフィールドとstart_cityフィールドを確実に異なるものにするためにクロスチェックを実行している。
<form id="get_starting_and_ending_cities"> <field name="start_city"> <grammar src="http://www.grammars.example/voicexml/city.gram"/> <prompt> 出発地はどこですか? </prompt> </field> <field name="end_city"> <grammar src="http://www.grammars.example/voicexml/city.gram"/> <prompt> 目的地はどこですか? </prompt> </field> <filled mode="any" namelist="start_city end_city"> <if cond="start_city == end_city"> <prompt> 同じ都市間を飛ぶことはできません。 </prompt> <clear/> </if> </filled> </form>
もし<filled>要素がフィールド項目内に存在するなら、それはユーザ入力によりフィールドの値が満たされた場合に実行するアクションを指定する。これは単一のフィールド項目に対してトリガされるフォームレベルの<filled>要素のための簡略記法である。
<form id="get_city"> <field name="city"> <grammar src="http://www.ship-it.example/grammars/served_cities.gram"/> <prompt> どこの都市ですか? </prompt> <filled> <if cond="city == '松ヶ崎空港'"> <prompt> 松ヶ崎空港への業務は来年終了するので注意してください。 </prompt> </if> </filled> </field> </form>
ユーザ入力の収集後、すべての名前があがっているfieldがセットされると、処理系はドキュメントオーダ内のそれぞれの<filled>要素を見る。(field内のものとform内のものとはより好みしない)発言によりマッチされたコンディションを持つそれらは、残っていないか、制御が移るもしくはイベントを投げ掛けるまでオーダ内で実行される。
属性:
mode | all(デフォルト)かanyのどちらかである。anyの場合、アクションは指定されたフィールドのいずれかが直前のユーザ入力により満たされたとき実行される。allの場合、アクションは指定された全てのフィールドが満たされており、少なくとも1つのフィールドが直前のユーザ入力で満たされたとき実行される。フィールド項目内の<filled>要素はmodeを指定できない。 |
namelist | トリガするためのfield。form内の<filled>にとって、namelistデフォルトはformのfield項目の名前(明示と暗示)である。field項目内の<filled>要素はnamelistを指定できない。;この場合namelistはfield項目名である。 |
<meta>要素はHTML内のそれと同様に、ドキュメントの内容よりもむしろドキュメントについてのデータであるmeta-dataを指定する。<meta>のタイプは2種類ある。1つ目のタイプは全体としてドキュメントのプロパティmeta-dataを指定する。例えば、VoiceXMLドキュメントの管理者を指定する。
<?xml version="1.0"?> <vxml version="1.0"> <meta name="maintainer" content="jpdoe@anycompany.example"/> ...... </vxml>
処理系はこの情報を使用することができる。例えば管理者にemailでエラー報告をするためである。
VoiceXMLは要求されたmeta-dataプロパティを指定することはないが、以下は推薦される。
author | 記述した作者情報 |
copyright | コピーライト通知 |
description | サーチエンジンへのドキュメントの説明 |
keywords | ドキュメント説明のキーワード |
maintainer | ドキュメント管理者のメールアドレス |
robots | ロボット型サーチエンジンへの指示 |
2つ目のタイプはHTTPレスポンスヘッダを指定する。以下の例では、最初の<meta>要素はドキュメントのキャッシュを防止する満了日をセットする;2つ目の<meta>要素はDateヘッダをセットする。
<?xml version="1.0"?> <vxml version="1.0"> <meta http-equiv="Expires" content="0"/> <meta http-equiv="Date" content="Thu, 12 Dec 1999 23:27:21 GMT"/> </vxml>
<meta>の属性:
name | meta-dataプロパティの名前 |
content | meta-dataプロパティの値 |
http-equiv | HTTPレスポンスヘッダの名前。nameかhttp-equivのどちらかは必ず指定されなければならない。 |
<property>要素はプロパティの値をセットする。プロパティは認識プロセス、タイムアウト、キャッシングポリシーなどのようなプラットフォームの振る舞いに影響する値をセットするために使用される。
プロパティは全てのアプリケーション、<vxml>レベルの全てのドキュメント、<form>または<menu>での特定の対話、または特定のフォーム項目間で定義されるかもしれない。プロパティはそれらの親要素と、親のすべての後続要素に適用する。低レベルなプロパティは、より高レベルなプロパティに上書きされる。アプリケーションルートドキュメント内で指定されたプロパティは、アプリケーション内の全てのドキュメントのプロパティにデフォルト数値を渡す。;単一のドキュメント内で指定されたプロパティは、アプリケーションルートドキュメント内でプロパティ値を上書きされる。
<property>要素は、timeoutやbargeinのような要素属性によりデフォルト数値の指定に用いられる。例えば、特定のform内の全てのpromptにおいてbargeinを無効にするためには次のように指定する:
<form id="no_bargein_form"> <property name="bargein" value="false"/> <block> <prompt> この導入プロンプトに割り込むことはできません。 </prompt> <prompt> このプロンプトもできません。 </prompt> <prompt bargein="true"> しかし <emp>can</emp> へ割り込むことができます。 </prompt> </block> .... </form>
プロパティはまた、プラットフォーム指定データとセッティングを指定するためにも使われる。例えば、特定のドキュメントによるそれぞれの録音以前に1秒の無音を追加するためのプラットフォーム指定プロパティをセットする:
<?xml version="1.0"?> <vxml version="1.0"> <property name="example.acme.endpointing.record_init_silence" value="1s"/> ... 録音された対話はここに来ます ...
汎用音声認識プロパティはJava Speech APIに従っている。
(http://www.javasoft.com/products/java-media/speech/index.html参照):
confidencelevel | 音声認識信頼度、0.0から1.0の間の浮動小数点数。処理内のエンジンの信頼がこの境界より下がるとき、結果は退けられる。(nomatchイベントが投げ掛けられる)0.0の数値の意味は、認識に必要とされる最低の信頼であり、1.0は最大の信頼を要求している。デフォルト値は0.5である。 |
sensitivity | 敏感度のセット。1.0は無音入力に対し高感度であることを意味する。0.0はノイズにあまり反応しないことを意味する。デフォルトは0.5。 |
speedvsaccuracy | 早さと正確さのバランスの要求を指定するヒント。0.0は最速の認識を示し、1.0は最高の正確さを意味する。デフォルトは0.5。 |
completetimeout | アクティブな文法が合致されるときに使う会話のタイムアウト値。デフォルトはプラットフォーム依存。付録F参照 |
incompletetimeout | アクティブな文法が合致されたときに使う、会話のタイムアウト。デフォルトはプラットフォーム依存。付録F参照 |
いくつかの汎用プロパティはDTMF文法認識に適する。
interdigittimeout | DTMF入力を認識するときに使う数字入力タイムアウト値。デフォルトはプラットフォーム依存である。付録F参照 |
termtimeout | DTMF入力を認識するときに使う終端タイムアウト。デフォルト値は"0s"である。付録F参照 |
termchar | DTMF入力認識用の終端DTMF文字。デフォルト値は"#"。付録F参照 |
これらのプロパティは重要なプラットフォームpromptをあて、サイクルを収集する。
bargein | bargein属性はpromptのために使われる。これがtrue(デフォルト)にセットされているとbarge-inを許している。 |
timeout | プラットフォームにより投げ掛けられるnoinputイベントの後の時間。デフォルト値はプラットフォーム依存。付録F参照 |
これらのプロパティは新しいドキュメントとリソースのフェッチングに適する。
caching | フェッチングのときキャッシュを決して保管しないsafeか、キャッシュを常に保管するfast。デフォルトはfast。 |
audiofetchhint | プリフェッチされた音声により対話処理を最適化すべきかをプラットフォームに指示する。可能な値は、必要になるまで決してフェッチされず、必要になったときのみ音声がフェッチされるsafe;プリフェッチを許可するがプラットフォームに強要はしないprefetch;音声フェッチのストリームを許すstreamのどれかである。デフォルトはprefetch。This tells the platform whether or not it can attempt to optimize dialog interpretation by pre-fetching audio. The value is either safe to say that audio is only fetched when it is needed, never before; prefetch to permit, but not require the platform to pre-fetch the audio; or stream to allow it to stream the audio fetches. The default value is prefetch. |
documentfetchhint | ドキュメントがpre-fetchされるかどうかをプラットフォームに教える。値はsafe(デフォルト)かprefetch。 |
grammarfetchhint | 文法がpre-fetchされるかどうかをプラットフォームに教える。値はprefetch(デフォルト)またはsafe。 |
objectfetchhint | <object>用のURIコンテンツがpre-fetchされるかどうかをプラットフォームに教える。値はprefetch(デフォルト)か、safe。 |
scriptfetchhint | スクリプトがpre-fetchされるかどうかを教える。値はprefetch(デフォルト)か、safe。 |
fetchaudio | ドキュメントがフェッチされているのを待つ間に再生するための音声のURI。デフォルトは音声を再生しない。音声、文法、object、script用のfetchaudioプロパティはない。 |
fetchtimeout | フェッチのタイムアウト。デフォルト値は、プラットフォーム依存。 |
このプロパティは使用するための入力の形態を決定する。
inputmodes | 可能な入力モード:dtmfとvoice。両方のモードがサポートされているプラットフォーム上では、inputmodesのデフォルトは"dtmf voice"である。DTMFが不可能にするには"voice"にセットする。これは雑音の多い環境で音声認識を切るために存在する。他は、DTMFであることを常に期待される入力を切ることにより音声認識リソースを保存するために存在する。 |
最後の例はこれらの複数のレベルで使用されるプロパティを示す。
<?xml version="1.0"> <vxml version="1.0"> <!-- ページのデフォルト特性をセットする --> <property name="caching" value="safe"/> <property name="audiofetchhint" value="safe"/> <property name="confidence" value="0.75"/> <form> <!-- このフォームのデフォルトは優先される --> <property name="confidence" value="0.5"/> <property name="bargein" value="false"> <grammar src="address_book.gram" type="application/x-jsgf"/> <block> <prompt> ようこそ音声アドレス帳へ。 </prompt> </block> <initial> <!-- デフォルトの時間切れが優先される --> <property name="timeout" value="5s"/> <prompt> 誰に電話したいですか? </prompt> </initial> <field name="person"> <prompt> 電話したい人の名前を言ってください。 </prompt> </field> <field name="location"> <prompt> 電話したい人の住所を言ってください。 </prompt> </field> <field name="confirm" type="boolean"> <!-- Use actual utterances to playback recognized words, rather than returned slot values --> <prompt> <value expr="location$.utterance"/>の <value expr="person$.utterance"/> に電話すると言いました。 これでよろしいですか? </prompt> <filled> <if cond="confirm"> <submit next="http://www.messagecentral.example/voice /make_call" namelist="person location" /> </if> <clear/> </filled> </field> </form> </vxml>
<param>要素はsubdialogまたはobjectへ通過させる数値を指定するために使う。HTMLの<PARAM>要素をモデルとしている。
属性:
name | objectまたはsubdialogが呼び出されるとき、このパラメータに結び付く名前。 |
expr | nameと結び付く値を計算する表現。 |
value | nameと結び付く内部文字列値。 |
valuetype | 1つのdataまたはref、デフォルトはdata;もし値がdataまたはref(URI)と結び付くなら、objectを指すために使われる。これは<subdialog>では使われない。 |
type | もしvaluetypeがrefなら、URIにより渡される結果のMIMEタイプ。;<object>内の<param>の使用にのみ関連する。 |
正確に1つのexprまたはvalueは渡されなければならない。valuetypeとtypeの使用は、汎用で任意であるが、それらはobject指定により要求されるかもしれない。<param>が<subdialog>要素に含まれるとき、それにより指定される数値は呼び出されたsubdialog内の対話<var>要素を初期化するために使用される。<param>が<object>内に含まれるとき、パラメータデータの使用は呼び出されるobjectを指定し、かつVoiceXML指定の有効範囲の外にある。
以下は、<object>の一部として使用される<param>の使用の例である。この場合、最初の2つの<param>要素は表現(valuetype="data"の暗示)を持ち、3つ目の<param>は明白な値を持つ。そして4つ目はtext/plainのMIMEタイプを返すURIである。このデータの目的はobjectを指定することである。
<object name="debit" classid="method://www.recordings.example/prompts/credit/jesse.jar"/> <param name="amount" expr="document.amt"/> <param name="vendor" expr="vendor_num"/> <param name="application_id" value="ADC5678-QWOO"/> <param name="authentication_server" value="http://auth_svr.example" valuetype="ref" value="text/plain"/> </object>
次の例は<subdialog>とともに使用される<param>を示している。この場合、2つのexprはsubdialog formの有効範囲内で変数を初期化するために使用されている。
呼び出し側フォーム
<form> <subdialog name="result" src="http://another.example/#getssn"> <param name="firstname" expr="document.first"/> <param name="lastname" expr="document.last"/> <filled> <submit namelist="result.ssn" next="http://myservice.example/cgi-bin/process"/> </filled> </subdialog> </form>
http://another.exampleの副対話
<form id="getssn"> <var name="firstname"/> <var name="lastname"/> <field name="ssn"> <grammar src="http://grammarlib/ssn.gram" type="application /x-jsgf"/> <prompt> 社会保障番号を言ってください。 </prompt> <filled> <if cond="validssn(firstname,lastname,ssn)"> <assign name="status" expr="true"/> <return namelist="status ssn"/> <else/> <assign name="status" expr="false'/> <return namelist="status"/> </if> </filled> </field> </form>
<subdialog>内での<param>の使用はサーバサイドスクリプティングを使用することなくsubdialogにデータを送る方法として便利である。
実行可能内容(executable content)は、手続き的論理のブロックを参照する。そのようなロジックは次の場所に現れる:
この章では、実行可能内容において出現しうる要素について述べる。
この要素は変数を宣言する。これは実行可能内容においては<form>または<vxml>の子として発生しうる。
<var name="phone" expr="6305551212"/> <var name="y" expr="document.z+1"/>
実行可能内容において発生すれば、それは、<block>、<filled>、または、キャッチ要素と関連していた無名の有効範囲において変数を宣言する。<var>が実行されるときのみ、この宣言が行われる。その変数がこの有効範囲において既に宣言されるならば、次の宣言は、割当ての役割を果たすことになる(ECMAScriptと同様に)。
<var>が<form>の子供であるならば、それは、その<form>の対話有効範囲において変数を宣言する。6.6.1.章において示されたformの初期化フェーズの間に、この宣言が行われる。<var>は、フォーム項目ではない。従って、FIAのメインループによって訪れられない。<var>が<vxml>の子であるならば、それは、ドキュメント有効範囲において変数を宣言する。この宣言は、ドキュメントが初期化されるときに行われる;初期化は、ドキュメント中の出現順に行われる。
name | 結果を保持するであろう変数の名前。 |
expr | (任意の)変数の初期値。もしexpr属性がないならば、その変数は、その現在の値を保持する。変数は初期値を与えられないならば、ECMAScriptのundefined値によって初期化される。 |
<assign>は、値を変数に割り当てる:
<assign name="flavor" expr="'chocolate'"/> <assign name="document.mycost" expr="document.mycost+14"/>
属性は、以下を含む。
name | 割り当てられた変数の名前に割り当てられる。 |
expr | 変数の新しい値。 |
<clear>は、1以上のフォーム項目をリセットする。
リセットは以下を含む。
例えば:
<clear namelist="city state zip"/>
その属性は、以下である。
namelist | リセットされるフォーム項目の名前。指定されていないときは現在のフォームにおける全てのフォーム項目がクリアされる。 |
<if>は、条件付の論理のために使われる。これは<else>と<elseif>のオプションを持つ。
<if cond="total > 1000"> <prompt> お金が足りません。 </prompt> <throw "com.xyzcorp.acct.toomuchspent"/> </if> <if cond="amount < 29.95"> <assign name="x" expr="amount"/> <else/> <assign name="x" expr="29.95"/> </if> <if cond="flavor == 'バニラ'"> <assign name="flavor_code" expr="'v'"/> <elseif cond="flavor == 'チョコレート'"/> <assign name="flavor_code" expr="'h'"/> <elseif cond="flavor == 'ストロベリー'"/> <assign name="flavor_code" expr="'b'"/> <else/> <assign name="flavor_code" expr="'?'"/> </if>
<prompt>カウント属性が無意味であるということを除けば、promptは、それらの十分な一般性における実行可能内容に現れうる。特に、condは、実行可能な内容に使われうる。promptは<prompt>と</prompt>で囲まれているか、もしくはPCDATAを用いて表される。どこででも<prompt>は許される。PCDATA xyzは、<prompt>xyz</prompt>として正確に翻訳される。
<nomatch count="1"> ドアを開くために、あなたのコードをはっきりと言って下さい。 </nomatch> <nomatch count="2"> <prompt> これが <emp> 最後の </emp> 猶予です。 </prompt> </nomatch> <nomatch count="3"> 入場は許可できません。 <exit/> </nomatch>
FIAが期待するのは、イベントの処理においてキャッチ要素が適切なプロンプトをキューに入れることである。しかしFIAは通常、キャッチ要素の実行後の繰り返し処理においては、プロンプト選択とキューイングは行わない。ただし、キャッチ要素の中でrepromptが実行された場合には、FIAは通常のプロンプト選択とキューイングを行い、フォーム要素のプロンプトカウンタをインクリメントする。
例えば、以下のnoinputによるキャッチは、次のフォーム要素においてプロンプトが選択され再生されることを期待している:
<field name="want_ice_cream" type="boolean"> <prompt> デザートにアイスクリームはいかがですか? </prompt> <prompt count="2"> アイスクリームが欲しい場合は「はい」と言って下さい。 アイスクリームがいらない場合は「いいえ」と言って下さい。 </prompt> <noinput> 聞き取れません。 <reprompt/> <!-- 次のプロンプトを選択させ再生させる --> </noinput> </field>
ユーザが何もしゃべらなかった場合:
H:(沈黙)
C:聞き取れません。
C:アイスクリームが欲しい場合は「はい」と言って下さい。アイスクリームが
いらない場合は「いいえ」と言って下さい。
H:(沈黙)
C:聞き取れません。
C:アイスクリームが欲しい場合は「はい」と言って下さい。アイスクリームが
いらない場合は「いいえ」と言って下さい。
H:いいえ。
<reprompt>がない場合,ユーザにはこのように聞こえる。:
C:デザートにアイスクリームはいかがですか?
H:(沈黙)
C:聞き取れません。
C:聞き取れません。
H:いいえ。
<reprompt>がcatchにおいて実行されないならば、それからFIAが選択されたフォーム項目のprompt選択、そして、列を作って待っているフェーズを飛ばすことを示す。フォーム項目のpromptカウンタは、そこでインクリメントされない。<reprompt>が実行されるならば、それからFIAはフォーム項目のprompt選択列を作って待っているフェーズを実行する。これは、フォーム項目のpromptカウンタをインクリメントする。<reprompt>によって、プレイされる前のpromptは決めない、しかし一般にpromptカウンタの現在の値、及び、promptコンディションの現在の値に基づいてプレイされるpromptを決める。
<goto>は、以下の様に使われる。
他のフォーム項目への遷移に、フォーム項目名がECMAScript式を用いて計算されるならば、nextitemまたは、expritemを使う:
<goto nextitem="ssn_confirm"/> <goto expritem="(type==12)? 'ssn_confirm' : 'reject'"/>
同じドキュメントにおける他の対話に行くために、URIフラグメントのみによってnext(或いはexpr)を使う:
<goto next="#another_dialog"/> <goto expr="'#' + 'another_dialog'"/>
他のドキュメントへの遷移に、URIと共にnext(或いはexpr)を使う:
<goto next="http://flight.example/reserve_seat"/> <goto next="./special_lunch/#wants_vegan"/>
URIは、絶対的もしくは、現在のドキュメントに関係がある。対話のid属性の値の一致するフラグメントを使う次のドキュメントにおいて起動対話を指定してもよい。フラグメントが指定されないならば、そのドキュメントにおける最初の対話が選択される。現在のドキュメントにおいて他の対話へ推移することは、古い対話の変数は失われることを示す。これは対話がその対話自身に推移する場合においてさえも同様である。他のドキュメントへの推移は、同様に古いドキュメントレベル変数を下げる。これは、たとえ新しいドキュメントが遷移を行っている1つと同じであるとしても同様である。データが多重ドキュメントを横断して固執することを望むならば、データをアプリケーション有効範囲に格納すればよい。
<goto>の属性は以下である:
next | 遷移するURI。 |
expr | URIをもたらすECMAScript式。 |
nextitem | 現在のformの中で次に訪れるフォーム項目の名前。 |
expritem | 次に訪れるformitemの名前をもたらすECMAScript式。 |
caching | 12.1.参照 |
fetchaudio | 12.1.参照 |
fetchhint | 12.1.参照 これは、documentfetchhintプロパティに履行しない。 |
fetchtimeout | 12.1.参照 |
expr、nextitemまたは、expritemのうちの1つは、指定されなければならない。
<submit>は、取得された新しいドキュメントに遷移するという点において<goto>に類似している。<goto>と異なるのは、変数の値をHTTP GETまたはPOST経由でドキュメントサーバに提出(submit)させる点である。例えば、いくつかのフォーム項目の値をサーバに提出するためには、以下のようにする:
<submit next="log_request" method="post" namelist="name rank serial_number" fetchtimeout="100s" fetchaudio="audio/brahms2.wav"/>
<submit>は以下の属性を含む:
next | クエリーが提出されるURI。 |
expr | 与えられたECMAScript表現にしたがってURIが動的に決定されることを除けばnextと同じである。nextまたは、exprのうちの1つが必要とされる。 |
namelist | 提出する変数のリスト。デフォルトでは名前を持つ全てのフィールド項目変数が提出される。namelistが与えられれば、それは個々の変数参照を含み得る。 |
method | リクエストのメソッド:get(デフォルト)もしくはpost。 |
enctype | 提出されたドキュメントのMIMEエンコーディング形式。デフォルトはapplication/x-www-form-urlencoded。インタプリタは他のエンコーディング形式をサポートすることができる。 |
caching | 12.1.参照 |
fetchaudio | 12.1.参照 |
fetchhint | 12.1.参照 documentfetchhintプロパティをデフォルトとする。 |
fetchtimeout | 12.1.参照 |
ECMAScriptオブジェクトoが提出のターゲットとなった場合は、全てのそのオブジェクトの(ECMAScriptにおける)フィールドf1、f2、...はo.f1、o.f2、などの名前を用いて提出される。
処理コンテクストへ制御を返し、次に行うべき処理の決定を委ねる。この要素により、全てのロードされたドキュメントを終了する。<subdialog>の呼び出しから戻る<return>要素とはこの点が異なる。<subdialog>によって新しいドキュメント(またはアプリケーション)が起動されたなら、<return>はドキュメントを中止させるが、その実行は<subdialog>終了後に再開する。
一度<exit>が処理コンテクストに制御を返せば、制御は処理コンテクストが自由に行うことができる。例えば、ユーザのためにトップレベルメニューを再生したり、電話回線を切断したり、ユーザの通話をオペレーターに転送する、などが考えられる。
属性は以下の通り:
expr | リターン表現(例:"0"、または、"oops!")。 |
namelist | インタープリタ文脈に戻る変数名。デフォルトは、変数を返さないことである;これは、インタープリタ文脈が空のECMAScriptオブジェクトを受け取ることを意味する。 |
リターンは、subdialogの実行を終え、そして、コントロール及び、データを呼び出し対話に返す。それらの属性は、以下である。
event | 戻る。その後、このeventを投げ掛ける。 |
namelist | 呼び出し対話に戻される変数名。そのデフォルトは、変数を返さないことである;これは、その呼び出し側が空のECMAScript対象を受け取ることを意味する。 |
subdialogから戻る際、eventは、呼び出しポイントで投げ掛けられうる、または、データは、ECMAScriptオブジェクトとして返される。subdialogとして実行していないとき、実行されるreturnは、semantic errorを投げかける。下の例は、subdialogが認識できる結果を獲得することができないとき、subdialogからその呼び出し対話まで増やされたeventを示す。同じくそれは、正常なコンディションの下で返されたデータを示す。
呼び出し側フォーム
<form> <subdialog name="result" src="#getssn"> <nomatch> <!-- subdialogによって返されるイベントが無いということは、 正当な社会保障番号が無いことを示す。--> <goto next="http://myservice.example/ssn-problems.vxml"/> </nomatch> <filled> <submit namelist="result.ssn" next="http://myservice.example/cgi-bin/process"/> </filled> </subdialog> </form>
社会保障番号を得るための subdialog
<form id="getssn"> <field name="ssn"> <grammar src="http://grammarlib/ssn.gram" type="application/x-jsgf"/> <prompt> 社会保障番号を言って下さい。 </prompt> <nomatch count=3> <return event="nomatch"/> </nomatch> <filled> <return namelist="ssn"/> </filled> </field> </form>
<nomatch>のためのsubdialogイベントハンドラが3回目の失敗のときに始動される。そのとき、それはsubdialogから戻り、そして呼び出し対話の文脈において投げられるためのnomatchイベントを加える。この場合、呼び出し対話は<filled>(そこで、その結果としての動作は<goto>を実行することである。)よりむしろ、その<nomatch>ハンドラを実行するであろう。正常なコンディションの下で、認識された社会保障番号が獲得された後、subdialogの<filled>は実行される。そして、この値は呼び出し対話に返されresult.ssnとしてアクセス可能となる。
処理コンテクストに回線を切断させる。その結果、処理コンテクストは、telephone.disconnected.hangupイベントを投げる。これをキャッチすることによりクリーンアップ処理が可能である。
<disconnect/>
<disconnect>は、<exit>と異なり、処理コンテクストに強制的に回線を切断させる。
<script>は、クライアント‐サイド作成の言語コードのブロックの仕様を許し、そしてHTMLの<SCRIPT>に類似している。例えば、このドキュメントは、階乗を計算するscriptを持っている。
<?xml version="1.0"?> <vxml version="1.0"> <script> <![CDATA[ function factorial(n) { return (n <= 1)? 1 : n * factorial(n-1); } ]]> </script> <form id="form"> <field name="fact" type="number"> <prompt> 数を1つ言って下さい。その階乗を計算します。 </prompt> <filled> <prompt> <value expr="fact"/> 階乗は <value expr="factorial(fact)"/> </prompt> </filled> </field> </form> </vxml>
<script>は、<vxml>において、もしくは、実行可能内容(<filled>,<if>, <block>, <catch>,もしくは短いformの<catch>)において発生する。ドキュメントがロードされた直後、<vxml>におけるスクリプトが評価される(ドキュメント順に<var>と一緒に)。他の実行可能なタグのように、実行可能な内容における<script>は、実行される(現状では遭遇して)。
<script>は、次の属性を持っている:
src | それが外部であるならば、scriptの位置を指定するURI。 |
charset | srcによって示されたscriptのキャラクタエンコーディング。 |
caching | 12.1.参照 |
fetchhint | 12.1.参照 これは、scriptfetchhintプロパティに履行しない。 |
fetchtimeout | 12.1.参照 |
各<script>は、それが含むタグの有効範囲において実行される。すなわち、これ自体の有効範囲を所有していない。
ここにformの対話有効範囲において、時間変数を初期化するscriptを含むblockによる時間を告げるサービスがある:
<?xml version="1.0"?> <vxml version="1.0"> <form> <var name="hours"/> <var name="minutes"/> <var name="seconds"/> <block> <script> var d = new Date(); hours = d.getHours(); minutes = d.getMinutes(); seconds = d.getSeconds(); </script> </block> <field name="hear_another" type="boolean"> <prompt> 現在の時刻は <value expr="hours"/> 時、 <value expr="minutes"/> 分、 <value expr="seconds"/> 秒です。 </prompt> <prompt> 他に聞きたい時間はありますか? </prompt> <filled> <if cond="hear_another"> <clear/> </if> </filled> </field> </form> </vxml>
ECMAScript有効範囲(http://www.ecma.ch/stand/ECMA-262.htmのsection 10.1.4参照)は<var>の発生した中で設定される。そして<var>で宣言された変数が関連していた有効範囲に入れられる。全ての変数は、ECMAScript scriptもしくはVoiceXMLのタグによって、割り当てられるか、参照を付けられる前に宣言されなければならない。
時間指示は、W3CのCascading Style Sheet推薦に使われるものに従っている
(http://www.w3.org/TR/REC-CSS2/syndata.html#q20)。それらは、任意の時間の単位識別子を伴う符号なし整数から成る。時間の単位識別子は、以下である。
フォーム処理アルゴリズム(FIA)はユーザと、VoiceXMLのformやmenuとの間の対話を制御する。menuは文法の動作が要素で構成されたようなひとつのfieldを含むformとして考えることができる。
FIAは以下の処理を行わなければならない:
はじめに、FIAで使用するいくつかの言葉とデータ構造を定義する。
有効文法集合(active grammar set) | VoiceXMLインタプリタコンテキストの収集作業中で有効な文法の集合。 |
発話(utterance) | ユーザが言ったこと、入力したことの要約。照合される特定の文法や、slot名/値の組を記録した辞書も含む。例:grammar 123 was matched, and the slots are from_city ='chicago', to_city='new orleans', and fight_num='2233'. |
実行する(execute) | 実行可能コンテンツ(block、満たされたaction、いくつかの満たされたactionの集合、のうち1つ)を実行すること。実行中にあるイベントが発生すると、その実行可能コンテンツの実行は中止される。そのとき、適当なイベントハンドラが実行され、これであるform item、次のformの主ループ(mainloop)の繰り返し作業、formの外への回復制御を行う。 |
以下にFIAの概念を示す。FIAは初期発話無し、又は別のダイアログから回って来た初期発話で始めることができる。
// // Initialization Phase(初期化) // foreach (ドキュメント内の出現順に <var> と form item変数) 変数を宣言し、もしexpr属性があればその値に初期化する。 さもなくばundefinedにする。 foreach (field item) promptカウンタを宣言し、1にセットする。 if (initial itemがある) promptカウンタを宣言し1にセットする。 if (ユーザが別のformにいる間に、現在のformの文法と対応する発話によって) { 下記のmainループに入る。ただしセレクトフェーズではなくプロセス フェーズからスタートする:なぜなら、すでに処理すべきコレクションを 持っているからである。 } // // Main Loop: 次のform itemを選択し、それを実行する。 // while (true) { // // Select Phase(選択):visitするためのform itemを選択する。 // if ( 直前のmain loopのiterationが<goto nextitem>で終わった。) 次のフォーム項目を選択する。 else if (unsatisfied guard conditionのform itemがある。) ドキュメント中のそのようなform itemの最初のものを選択する。 else <exit/>を実行する。 -- fullであり、遷移が指定されていない。 // // Collect Phase(収集):選択されたform itemを実行する。 // // そのform itemのpromptをキューに入れる。 unless (直前のloopのiterationが"<reprompt>がない"というcatchで 終わった。) { そのform item用に適切な複数のpromptを選択する。 次のcollect操作の前に、選択された複数のpromptを再生のために キューに入れる。 現在のform itemのpromptカウンタをインクリメントする。 } // そのform itemのための文法をactivateする。 if (そのform itemがモーダルである。 ) 現在のform itemに文法があればそれを有効文法集合とする。 (注:form itemの中には文法を全く持てないものもある。 例:<block>。) else 現在のform itemの文法と、現在のフォームと、それぞれのスコープ 中の全ての文法を現在のドキュメントと現在のapplicationルート ドキュメントと<subdialog>コールチェインの上位の要素の activeな文法セットとする。 // form itemの実行。 if (<field>が選択されていれば) ユーザからの発話またはイベントを収集。 else if (<record>が選択されていれば) ユーザからの発話(録音されたバイト列をname/valueペアとして) またはイベントを収集。 else if (<object>が選択されていれば) objectを実行し、返ってきたECMAScript値をそのobjectの form itemの変数にセットする。 else if (<subdialog>が選択されていれば) objectを実行し、返ってきたECMAScript値をそのobjectの form itemの変数にセットする。 else if (<transfer>が選択されていれば) transferを実行する。そして、もしwaitがtrueならばform itemの 変数に、result status indicatorの返り値をセットする。 else if (<initial>が選択されていれば) ユーザからの発話またはイベントを収集。 else if (<block>が選択されていれば) { 定義された値を、blockのform item変数に代入する。 blockの実行可能コンテキストを実行する。 } // // Process Phase(処理フェーズ):発話やイベントを処理する。 // // あるイベントの処理。 if (form itemの実行によってイベントが発生した。) { そのイベントに対する適当なcatchを見つける。 そのcatchを実行する(そのときFIAから抜ける可能性がある。) continue. } // 発話があった場合に限られる:外部の文法を処理。 if (発話がform外の文法に合った。) { if (その文法が<link>要素に属する。) FIAを抜け、<link>のgoto、又はthrowを実行する。 if (その文法がmenuの<choice>要素に属する。) FIAを抜け、<choice>のgoto、又はthrowを実行する。 // その文法が別のform(又はmenu)に属する。 別のform(又はmenu)のFIAに発話を渡し、そのform(又はmenu)に遷移 する。 } // このformからある文法に話し掛けたような発話の処理 // はじめ、発話のslot値を、相当するform item変数にコピーする。 "just_filled"フラグをすべてクリアする。 foreach (ユーザ発話の中にあるslot) { if (そのslotはfield itemに相当する。) { そのfield itemのform item変数に、そのslot値をコピーする 。 このfield itemの"just_filled"フラグを立てる。 } } // 少しでもfield itemが埋まっているなら、<initial>form item変数を セットする。 if (どのfield item変数もユーザ発話の結果として、セットされている。) <initial>form item変数をセットする。 // 次に、この発話が引き金となるあらゆる<filled>actionを実行する。 foreach (ドキュメン中にある<filled>action) { // form item変数を<filled>要求に限定する。 N = <filled>の"namelist"属性。 if (Nが"") { if (その<filled>がform itemの子である。) N = form itemのform item変数名 else if (その<filled>がformの子である。) N = そのformにあるすべてのform item変数名。 } // その<filled>は誘発されたか? if (あらゆるform item変数が、N="just_filled"な集合にある。 AND (その<filled>モードは"all"。 AND Nの中のall変数は埋まっている。) OR (その<filled>モードは"any"。 AND Nの中のany変数は埋まっている。)) その<filled>actionを実行する。 } }
ここでは、VoiceXMLの<grammar>要素においてJSGF(Java Speech Grammar Format)をどのように使用できるか説明する。
第10章によると、VoiceXMLでの文法は以下の要求を満たさなければならない。
JSGFは、文脈自由文法を記述する言語を提供することにより上記の一つ目の要求仕様を実現する。以下の表にJSGFの仕様の概要を示す。
仕様 | 意味 |
---|---|
word or "word" | words(終端記号、トークン)に""は不要 |
<rule> | 規則名(非終端記号)は<>で囲む |
[x] | 省略可能なx |
(...) | グループ分け |
x{tag text} | 任意の"tag"テキストは上記のいずれかに結合できる。 |
x* | 0回以上xが発生 |
x+ | 1回以上xが発生 |
xyz... | x、そしてy、そしてz、そして...となる一続きの順番列 |
x|y|z|... | x、又はy、又はz、又は...となる選択肢の集合 |
<rule>=x; | プライベート(狭義)な規則設定 |
public <rule>=x; | パブリック(広義)な規則設定 |
JSGF tag facilityは、アクション要求を記述するために値を(入力)フォームに提供するという二つ目の要求仕様を満たす方法を提供する。field文法の場合、文字列値は1つだけで良く、供給される値にはtagが使用される。tagの指定がない場合、発話内容自体が値として使用される。
第10章によると、文法要素はinlineかexternalのどちらかとなる。さらにJSGFの場合、inline文法は文法フラグメントか完全文法のどちらかとなる。以下に3つの場合について記述した。
ここでの<grammar>要素の内容は、JSGF規則の最も役に立つ部分である(JSGF用語で"規則展開(rule expansion)"と呼ぶ)。最もよくある場合では、非終端記号への参照が無く特別な予約語をXMLで記述する必要も無いので、クォーテーション付けやPCDATA要素の使用を必要とせずにinlineで規則展開を明確に記述することができる。従ってこのフォームは、ある一文において選択可能な複数の言い回しについての簡単なリストを表現するのに特に便利である。例を以下に示す。
<link event="help"> <grammar type="application/x-jsgf"> [please] help [me] [please] | [please] I (need | want) help [please] </grammar> </link> <field name="sandwich"> <grammar type="application/x-jsgf"> hamburger | burger {hamburger} | (chicken [sandwich]) {chicken} </grammar> </field>
はじめの例では、任意の言い回しで"help"を発話すればhelpイベントが投げられる。二つ目の例では、ユーザが"hamburger"か"burger"を発話すれば"sandwich"フィールドに値"hamburger"が与えられる。また、ユーザが"chicken"か"chicken sandwich"を発話すれば"sandwich"フィールドに値"chicken"が与えられる。
ここでの<grammar>要素の内容は、external文法への参照が可能で、1つ以上の規則設定が成されているような完全JSGF文法である。この場合、入力される文法内のすべてのパブリック規則が使用される。従ってこのフォームはXMLによる特別な予約語(普通はPCDATA要素)の使用を要求する。
完全JSGF文法はgrammar要素のsrc属性により指定されたURIで発見される。このときgrammar要素の内容は空でなければならない。指定されたURIは、以下のような形態をとる。
VoiceXMLは、プラットフォームが以下に示すような形式のオーディオファイルの録音・再生を提供できることを利点としている。
注:プラットフォームはA-lawもμ-lawも同時に提供しなくても良い。
オーディオ形式 | MIME形式 |
---|---|
Raw (ヘッダ無し) 8kHz8bitμ-law [PCM] single channel |
audio/basic (from http://ietf.org/rfc/rfc1521.txt) |
Raw (ヘッダ無し) 8kHz8bit A-law [PCM] single channel |
audio-x-alaw-basic |
WAV (REFFヘッダ)8kHz8bitμ-law [PCM] single channel |
audio/wav |
WAV (REFFヘッダ)8kHz8bit A-law [PCM] single channel |
audio/wav |
音声認識やDTMF認識に対する様々なタイミング特性は、ともにユーザ体験を定義する。これらの違うタイミングパラメータが作用する方法は、以下のタイミングダイアグラムで概説する。このダイアグラムでは、DTMF入力待ちやユーザ発話待ちは、ともに最後のプロンプトが再生し終わった時に開始される。
DTMF文法はユーザ体験に合わせて、タイムアウト、interdigitタイムアウト、条件タイムアウト、条件集合を使用する。これらの効果は以下のタイミングダイアグラムで示す。
タイムアウトパラメータは、ユーザがDTMF入力に失敗しているときに<noinput>イベントを投げるタイミングを決定する。(図5)
interdigitタイムアウトは、ユーザが追加DTMF入力に失敗したりDTMF文法が認識されなかったときにnomatchイベントを投げるタイミングを決定する。(図6)
以下の例は、追加のDTMF入力により対話の続行・終了が可能なDTMF文法があるときに、ユーザが追加入力を拒否したような状況である。(図7)
以下の例では、条件集合は空ではなく、interdigitタイムアウトが終了する前にユーザにより入力されている。つまり、ユーザDTMF入力の完了を意味する。ここで、条件集合は認識値の一部として含まれない。(図8)
以下の例では、最後のDTMF入力が追加DTMFを見込めないような対話終了点に文法を導いている。条件集合は空なので、適当な省略可能な終了記号は無い。従って認識は終了し、認識値が返される。(図9)
以下の例では、最後のDTMF入力が文法で許された追加DTMFがないような対話終了点に文法を導いている。もし条件集合が空でなければ、ユーザは省略可能な条件集合DTMFを入力できる。もし条件タイムアウト内にこの省略可能なDTMFを入力できなかったら、認識は終了し認識値が返される。もし条件タイムアウトが0秒(デフォルト値)ならば、省略可能な条件集合を待つことなく、文法で許された最後のDTMFの直後に認識値が返される。(図10)
この最後のDTMFの例では、最後のDTMF入力が文法で許された追加DTMFがないような対話終了点に文法を導いている。条件集合は空でないので、条件タイムアウト内でのユーザによる省略可能な条件集合の入力によって認識値が返される(条件集合を除いて)。(図11)
音声認識文法はユーザ体験に合わせて、タイムアウト、完全タイムアウト、不完全タイムアウトを使用する。これらの効果を以下のタイミングダイアグラムで示す。
以下に示す例では、タイムアウトパラメータは、ユーザが発話に失敗したときにnoinputイベントを投げるタイミングを決定する。(図12)
上の示す例で、ユーザが音声認識文法に合った発話をしたとする。その後発話がないまま完全タイムアウトが経過すると、認識値が返される。(図13)
上に示す例で、ユーザが音声認識文法には合わないが合法発話の接頭辞となる発話をしたとする。その後発話がないまま不完全タイムアウトが経過すると、nomatchイベントが投げられる。(図14)
これは、新要素におけるVoiceXMLの拡張例である。
<transcribe>要素は、ユーザの発話の録音を収集するfieldアイテムである。録音文字列はfieldアイテム変数に格納される。
<?xml version="1.0"?> <vxml version="1.0"> <form> <transcribe name="message" beep="true" maxtime="30s"> <prompt>What is the message you want to leave?</prompt> <nomatch count="2"> Try to make your message simpler. </nomatch> <nomatch count="3"> Transferring to operator. <goto next="queue_caller.pl"/> </nomatch> </transcribe> <field name="confirm" type="boolean"> <prompt>Your message is <value expr="message"/>.</prompt> <prompt>To send it, say yes. To discard it, say no.</prompt> <filled> <if cond="confirm"> <submit next="send_page.pl" namelist="message"/> </if> <clear/> </filled> </field> </form> </vxml>
すべての処理コンテキストが<transcribe>に対応するとは限らない。
<transcribe>の属性は以下の通りである。
name | 録音データを格納するfield1アイテム変数名 |
expr | formアイテム変数の初期値(デフォルトは未定義のECMAScript)値が初期化されると、そのformアイテム変数は、クリアされる場合を除いてアクセスされることはない。 |
cond | コンディションを表すブール値。formアイテムにアクセスするためにはtrueでなければならない。 |
modal | ブール値。ここがtrue(デフォルト)なら、録音を行う間すべてのより上位な音声認識文法とDTMF文法が無効となる。もしfalseなら、form、ドキュメント、アプリケーション、(実装済みなら)ドキュメント呼び出しの範囲にあたる音声認識文法とDTMF文法が有効になる。 |
beep | ブール値。trueなら録音直前に音が鳴る。デフォルトはfalse。 |
maxtime | 最大録音継続時間 |
finalsilence | 時間間隔。finalsilenceで指定した時間だけ無音状態が続くと発話終了と判断される。 |
dtmfterm | ブール値。true(デフォルト)ならDTMF入力で録音が終了される。DTMF音は録音に含まれない。 |
<transcribe>のシャドー変数(name$)は、録音がなされた後に以下のECMAスクリプトのプロパティを持つ。
name$.confidence | 録音における信頼水準(0.0-1.0)。0.0が最低信頼水準、1.0が最高信頼水準を示す。この値におけるより細かな説明はプラットフォームに依存する。 |
name$.termchar | dtmfterm属性がtrueならばユーザはDTMFキーを押すことにより録音を終了できる。シャドー変数name#termcharは、このとき押されたキーとなる(例:"#")。それ以外はNULLとなる。 |
name$.utterance | 未処理の認識された文字列。正確なトークンや綴りはプラットフォーム依存となる(例:"five hundred thirty"または"5 hundred 30"または"530")。例えば、"I need $125 by tonight."という最終的な録音において、この未処理発話は" I need a hundred and twenty five dollars by tonight"となるかもしれない。 |
以下にDTDの変更部分を示す。
<!--================================= Dialogs =============================--> ... <!ELEMENT form (%input; | %event.handler; | filled | initial | object | link | property | record | subdialog | transcribe | transfer | %variable;)* > <!ATTLIST form id ID #IMPLIED scope %scope; 'dialog' > ... !--============================= Audio Input =============================--> ... <!ELEMENT transcribe (%audio; | %event.handler; | filled | grammar | prompt | property)* > <!ATTLIST transcribe %item.attrs; beep %boolean; 'false' maxtime %duration; #IMPLIED modal %boolean; 'true' finalsilence %duration; #IMPLIED dtmfterm %boolean; 'true' > ...
以下にフォーム解釈アルゴリズム(FIA)の変更部分を示す。
// Execute the form item. if ( a <field> was selected ) Collect an utterance or an event from the user. else if ( a <record> was chosen ) Collect an utterance (with a name/value pair for the recorded bytes) or event from the user. else if ( a <transcribe> was chosen ) Collect an utterance (with a name/value pair for the transcription) or event from the user. else if ( an <object> was chosen ) Execute the object, setting the <object>’s form item variable to the returned ECMAScript value. ...