第三节 Form Items
|
|
|
form item就是一个<form>中的元素,该元素在form解释期间可以被访问。这些元素包括<field>、<block>、<initial>、<subdialog>、<object>、<record>和<transfer>元素。 |
|
所有的form item都有下面的特点: |
|
·它们都有一个变量,由name属性指定。该变量可以通过expr属性获得初始值。 |
|
·它们都有一个警戒条件,由cond指定。如果一个form item没有被填充,且它的警戒条件没有指定或值为true,则该form item可以被访问。 |
|
Form item可再细分为input item和control item,前者定义了该form的input item变量,后者用于帮助控制该form的input item的收集。Input item(<field>、<subdialog>、<object>、<record>和<transfer>)一般来说包含下面几个元素: |
|
·<filled>元素,它包含了一些在相应的input item被填充后要执行的操作。 |
|
·<property>元素,用于指定作用于该input item(<initial>元素也可以包含<property>元素)的property。 |
|
·<prompt>元素,用于指定相应的元素被访问时要播放的提示语。 |
|
·<grammar>元素,用于指定该input item(<subdialog>不能包含<grammar>元素)允许输入的语音或DTMF按键。 |
|
·<catch>元素及它的一些简写形式,用于指定作用于该input item(<initial>元素不能包含<catch>元素)的事件处理。 |
|
每个input item都有相应的一组影子变量。影子变量用于返回一个input item执行后的结果。而不是返回要存储于name属性的值。例如,在<field>的语法识别结果中有这次识别的confidence level(它是一个影子变量),获得这个值对我们可能有很大的帮助。影子变量的引用可以使用如下这种形式:name$.shadowvar,name就是该input item的name属性的值,shadowvar就是指定的影子变量名。影子变量是可写的,它的值可以被应用更改。例如,<field>返回的影子变量,confidence。下面的例子展示了怎样访问这个影子变量。 |
|
<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.0" xmlns="http://www.w3.org/2001/vxml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3.org/2001/vxml
http://www.w3.org/TR/voicexml20/vxml.xsd">
<form id="get_state">
<field name="state">
<prompt>Please say the name of a state. </prompt>
<grammar src="http://mygrammars.example.com/states.gram" type="application/srgs"/>
<filled>
<if cond="state$.confidence < 0.4">
<throw event="nomatch"/>
</if>
</filled>
</field>
</form>
</vxml>
|
|
在这个例子中,识别结果的confidence要经过检查,confidence值太低的结果不会被接受。 |
|
一、FIELD |
|
<field>是一个form item,用于收集用户输入,它的属性有: |
name |
该form item的form item变量,它的作用域为dialog,它保存了识别的结果,在所在的form的form item中,该form item变量名必须是唯一的,如果该变量名不是唯一的,在获取文档时会抛出error.badfetch事件,该变量名必须符合变量的命名规则,详见5.1节。 |
expr |
该form item变量的初始值,默认为ECMAScript 的undefined。如果给它一个初始值,该form item 将不会被访问,除非它被清零。 |
cond |
一个表达式,当它的结果值为true时,该form item才被访问。如果没有指定该属性值,也能被访问。 |
type |
该<field>的类型,即内置语法类型的名称(详见附录P)。平台对内置语法类型的支持是可选的。如果不支持一个指定的内置语法类型,要抛出一个error.unsupported.builtin 事件。 |
slot |
语法槽名,用于存放变量(如果没有指定,默认值为该变量名)。当所用的语法格式支持返回一组成对的槽/值(slot/value)的机制,且槽名与该form item变量名不同时,该属性就很有用。 |
modal |
如果它的值为false(默认值),在该field的收集阶段所有激活的语法都可以匹配;如果它的值为true,则只有该field的语法是允许匹配的,其它的都暂时失效。 |
|
表9:<field>元素的属性 |
|
下表是<field>元素的影子变量(shadow variables),该<field>的form item 变量名为name。影子变量utterance、 inputmode 和 interpretation的值必须和application.lastresult$ (详见5.1.5节)中相应变量的值一样。 |
name$.utterance |
被识别的词的原始串。正确的标记和拼写是依赖于平台的(例如“five hundred thirty”或“5 hundred 30”或只是“530”)。如果是DTMF语法,该变量将包含匹配的数字串。 |
name$.inputmode |
用户输入的模式,值为dtmf或voice。 |
name$.interpretation |
一个ECMAscript变量,它包含了用户输入的语义解释,详见3.1.5。 |
name$.confidence |
该<field>的confidence级别,它的取值范围为0.0-1.0,0.0表示最小的confidence,1.0表示最大的confidence。平台可以用utterance的confidence (application.lastresult$.confidence的值)作为name$.confidence 的值 ,<field>和utterance 级别的confidence之间的差别是依赖于平台的。 Confidence值更详细的解释是依赖于平台的,因为它的计算方法很可能每个平台不一样。 |
|
表10:<field>元素的影子变量 |
|
<一>、使用显式语法的<field> |
|
显示语法可以通过绝对的或相对的URI指定: |
|
<field name="flavor">
<prompt>What is your favorite ice cream?</prompt>
<grammar src="../grammars/ice_cream.grxml" type="application/srgs+xml"/>
</field>
|
|
也可以指定一个联机(inline)语法,下面的例子使用了W3C ABNF格式的语法。 |
|
<field name="flavor">
<prompt>What is your favorite flavor?</prompt>
<help>Say one of vanilla, chocolate, or strawberry.</help>
<grammar mode="voice" type="application/srgs">
#ABNF 1.0;
$options = vanilla | chocolate | strawberry
</grammar>
</field>
|
|
如果同时指定<grammar>元素的src属性和联机语法,平台会抛出error.badfetch事件。 |
|
<二>、使用依赖于平台的内置的显式语法 |
|
平台对内置资源的支持是可选的,如语音语法、DTMF语法和音频文件。这些资源使用平台特有的URI访问,例如http://localhost:5000/grammar/boolean,或者使用平台特有的方案(scheme),例如通常使用的“builtin”方案,“builtin:grammar/boolean”。如果平台支持访问内置资源,它应该支持访问基本的内置语法(见附录P)。例如: |
|
<grammar src="builtin:grammar/boolean"/>
<grammar src="builtin:dtmf/boolean"/>
|
|
上面的例子中,第一个<grammar>引用了内置的boolean语音语法,第二个<grammar>引用了内置的boolean的DTMF语法。 |
|
下面的<field>: |
|
<field type="sample">
<prompt>Prompt for builtin grammar</prompt>
</field>
|
|
和下面这个使用平台特有的内置语法的<field>,效果是一样的。 |
|
<field>
<grammar src="builtin:grammar/sample"/>
<grammar src="builtin:dtmf/sample"/>
<prompt>Prompt for builtin grammar</prompt>
</field>
|
|
sample是基本的内置<field>的type之一(如,boolean、date等)。 |
|
另外,依赖于平台的内置语法的URI可用来访问特定解释器环境支持的语法,我们建议平台特有的内置语法以“x-”开头命名,因为在将来的正式版本中不会使用该命名空间。如下: |
|
<grammar src="builtin:grammar/x-sample"/>
<grammar src="builtin:dtmf/x-sample"/>
|
|
<三>、使用<option>列表的<field> |
|
当要为<field>指定一组简单的可选项时,用<option>列表比用一个语法方便。<option>列表由包含于<field>元素中的一组<option>元素组成,每个<option>元素包含了用来产生语音语法的PCDATA,<option>的语法产生规则和2.2.5节中的<choice>一样。<option>有一个属性用于为每个<option>指定一个DTMF序列,还有一个属性用于控制要赋给该<field>元素的form item变量的值。当一个<option>元素被选定时,它的属性value的值决定了该<field>的影子变量和application.lastresult$的语义解释值。 |
|
下面的例子中的<field>元素给用户提供了三个选项,把被选定的application.lastresult$元素的value属性值赋给变量maincource: |
|
<field name="maincourse">
<prompt>
Please select an entree. Today, we are featuring <enumerate/>
</prompt>
<option dtmf="1" value="fish"> swordfish </option>
<option dtmf="2" value="beef"> roast beef </option>
<option dtmf="3" value="chicken"> frog legs </option>
<filled>
<submit next="/cgi-bin/maincourse.cgi" method="post" namelist="maincourse"/>
</filled>
</field>
|
|
该例子可能的流程: |
|
C: Please select an entree. Today, we're featuring swordfish; roast beef; frog legs.
H: frog legs.
C: (assigns "chicken" to "maincourse", then submits "maincourse=chicken" to /maincourse.cgi)
|
|
下面的例子展示了在一个form的<catch>元素中的<enumerate>元素的正确用法和错误用法,该form有几个<field>元素包含有<option>元素。 |
|
<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.0" xmlns="http://www.w3.org/2001/vxml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3.org/2001/vxml
http://www.w3.org/TR/voicexml20/vxml.xsd">
<form>
<block>
We need a few more details to complete your order.
</block>
<field name="color">
<prompt>Which color?</prompt>
<option>red</option>
<option>blue</option>
<option>green</option>
</field>
<field name="size">
<prompt>Which size?</prompt>
<option>small</option>
<option>medium</option>
<option>large</option>
</field>
<field name="quantity">
<grammar type="application/srgs+xml" src="/grammars/number.grxml"/>
<prompt>How many?</prompt>
</field>
<block>
Thank you. Your order is being processed.
<submit next="details.cgi" namelist="color size quantity"/>
</block>
<catch event="help nomatch">
Your options are <enumerate/>.
</catch>
</form>
</vxml>
|
|
该例子可能的流程: |
|
C: We need a few more details to complete your order. Which color?
H: help. (throws "help" event caught by form-level <catch>)
C: Your options are red, blue, green.
H: red.
C: Which size?
H: H: 7 (throws "nomatch" event caught by form-level <catch>)
C: Your options are small, medium, large.
H: small.
|
|
在上面的步骤,form级别的<catch>元素中的<enumerate>元素可以列举一些内容:“color”和“size”<field>中的<option>元素。然而,下一个<field>就不一样了: |
|
C: How many?
H: a lot. (throws "nomatch" event caught by form-level <catch>)
|
|
Form级别的<catch>元素中使用<enumerate>,导致平台抛出error.semantic事件。因为“quantity”<field>中没有包含任何可以列举的<option>元素。 |
|
有一种办法可以解决,就是在“quantity”<field>元素中加一个field级别的<catch>元素,如下: |
|
<catch event="help nomatch">
Please say the number of items to be ordered.
</catch
|
|
这样,“nomatch”事件被<field>中的<catch>捕获,下面是一个可能的流程: |
|
C: Please say the number of items to be ordered.
H: 50.
C: Thank you. Your order is being processed.
|
|
<enumerate>元素在2.2.4节中也有详细描述。 |
|
<option>元素的属性有: |
dtmf |
该<option>元素的DTMF序列,它的作用等同于一个简单的DTMF语法,和应用于该序列识别的DTMF<property>。它和DTMF语法不同的是,它的空格是不起作用的:dtmf=“123#”跟dtmf=“1 2 3 #”的效果是一样的。 |
accept |
值为exact (默认)或approximate。当其值为exact时,语音识别时需完全匹配该元素定义的文本;当其值为approximate,语音识别只需大概匹配该元素定义的文本(详见2.2.5节)。 |
value |
当用户选择该<option>时,赋给该<field>元素的form item变量的字符串,无论用户是使用语音输入还是DTMF按键输入。默认是使用<option>元素的CDATA内容赋值,这些CDATA开头和结尾的空格都被去掉了。如果<option>没有内容,就用DTMF序列代替。 |
|
表11:<option>元素的属性 |
|
使用<option>元素不排除同时使用<grammar>元素,结果将是这两个"语法"中的任一个的匹配。而在同一个<field>中同时出现两个<grammar>元素则意味着选项的逻辑或,即两个语法中只能匹配一个。 |
|
二、BLOCK |
|
<block>是form item,它包含的是可执行的内容,如果该<block>的form item 变量为undefined,且“cond”属性(如果有的话)值为true,它就会被执行。 |
|
<block>
Welcome to Flamingo, your source for lawn ornaments.
</block
|
|
当FIA进入<block>时,该<block>的form item 变量被自动的置为true。因此,每次的form调用中,<block>一般只被执行一次。 |
|
有时候,你可以更多地控制<block>。你可以给该form item 变量命名,通过赋值或清零控制<block>的执行。该变量在该form的dialog作用域内被声明。 |
|
<block>的属性有: |
name |
该form item变量名,它用来标记该<block>是否符合被执行的条件。默认为不可访问的内部变量。 |
expr |
该form item变量的初始值,默认为ECMAScript 的undefined。如果给该form item变量一个初始值,该form item就不会被执行,除非它的form item变量被清零。 |
cond |
它是一个boolean表达式,用来判定该form item是否可以访问。在会话之后,它的值必须为true。 |
|
表12:<choice>元素的属性 |
|
三、INITIAL |
|
在一个典型的混合主动式的form中,当FIA播放最初的form信息给用户时,就进入了<initial>元素,而不是进入计算机主导的模式,在计算机主导的模式中,每个field单独地被访问。和field item不同的是<initial>没有任何语法,也没有任何的<filled>操作。例如: |
|
<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.0" xmlns="http://www.w3.org/2001/vxml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3.org/2001/vxml
http://www.w3.org/TR/voicexml20/vxml.xsd">
<form id="get_from_and_to_cities">
<grammar src="http://www.directions.example.com/grammars/from_to.grxml"
type="application/srgs+xml"/>
<block>
Welcome to the Driving Directions By Phone.
</block>
<initial name="bypass_init">
<prompt>
Where do you want to drive from and to?
</prompt>
<nomatch count="1">
Please say something like "from Atlanta Georgia to Toledo Ohio".
</nomatch>
<nomatch count="2">
I'm sorry, I still don't understand.
I'll ask you for information one piece at a time.
<assign name="bypass_init" expr="true"/>
<reprompt/>
</nomatch>
</initial>
<field name="from_city">
<grammar src="http://www.directions.example.com/grammars/city.grxml"
type="application/srgs+xml"/>
<prompt>From which city are you leaving?</prompt>
</field>
<field name="to_city">
<grammar src="http://www.directions.example.com/grammars/city.grxml"
type="application/srgs+xml"/>
<prompt>Which city are you going to?</prompt>
</field>
</form>
</vxml>
|
|
如果在访问<initial>时抛出一个事件,则执行相应的事件处理。和其他的form item一样,如果<initial>的form item变量为undefined,且它的cond属性为true,它还是可以再次被访问的。如果用户的输入填充了一个或多个field item变量,则在任何一个<filled>操作被执行前,所有的<initial>form item变量都被置为true。 |
|
<initial>form item变量可以显式地被禁用,或重新被FIA访问。例如,在上面的例子中,<initial>的form item变量在第二个nomatch事件中被置为true,这样,FIA就不再处理<initial>元素,而去选定下一个form item,即一个<field>,它提示用户输入起点城市;同样的,<initial>元素的form item变量也可以被清零,这样,FIA就可以再次选定该<initial>元素。 |
|
在同一个form中可以有多个<initial>元素。只有cond属性为true且在文档中的顺序最靠前的一个<initial>元素会被访问。当该<initial>元素的form item变量被填充,该form 所有的<initial>元素都被置为true,因此FIA不会访问其他的<initial>元素。显式的重置一个或多个<initial>元素,可以使它们再次变为可用,甚至允许FIA在下一次的循环中选定另一个<initial>元素。 |
|
在FIA的一次循环中,<initial>元素的cond属性也可用来决定哪一个<initial>元素要被选定。一个应用可提供多个<initial>元素,但是用cond属性限定它们只能在特定的环境下才可用。例如,用cond属性来判断使初级还是高级操作模式,且只有在高级操作模式中使用元素。此外,如果在文档顺序中第一个<initial>元素的cond属性被指定了一个值,该值永远都不会实现,则该<initial>元素也永远不会被执行。如果每个<initial>元素的cond属性都有一个使它们不会被选定的值,则哪一个<initial>元素都不会被执行。 |
|
在访问<initial>元素时,一般的语法作用域规则也会起作用,详见3.1.3节。特别地,作用域为<field>元素内的语法都不会被激活。 |
|
注意,显式的给一个input item变量赋值,不会影响到<initial>元素的form item变量的值。 |
|
<initial>元素的属性: |
name |
该form item变量的名称,用于检测该<initial>元素是否为可选定的。默认为一个不可访问的内部变量。 |
expr |
该form item变量的初始值。默认为ECMAScript的undefined。如果赋一个初始值给它,该form item将不会被访问,除非该form item变量被清零。 |
cond |
ECMAScript表达式。只有当其结果值为boolean true,该代码块才被执行,否则不被执行。缺省时为 true。 |
|
表13:<initial>元素的属性 |
|
四、SUBDIALOG |
|
subdialog提供了重用相同的dialog和建立可重用应用库的一种机制。 |
|
在调用的dialog中的<subdialog>元素通过它的属性src或srcexpr调用了被调用的dialog(即subdialog)。Subdialog在一个新的执行环境中执行,该执行环境包括了该subdialog中所有的声明和状态信息,它的文档,应用根文档(如果有的话),计数器重置和变量初始化。当执行了一个<return>元素或<exit>元素,或再没有任何符合条件的form item可供FIA选定时,subdialog返回。<return>元素使控制和数据返回到调用的dialog(见5.3.10节)。当subdialog返回时,它的执行环境被删除,且调用dialog中的执行恢复。 |
|
<subdialog>元素所在的dialog和被调用的dialog的环境时互相独立的,即使这两个dialog是在同一个文档中。在被调用的dialog中是不能访问调用dialog的作用域链中的变量的。在两个执行环境中没有任何共享的变量实例。即使调用dialog和被调用dialog在同一个文档中,它们的执行环境包含的也是不同的变量实例。当调用dialog和被调用dialog在不同的文档中,但它们的根文档是同一个时,subdialog中的根变量同样是不同的变量实例。当subdialog返回时,所有应用于subdialog环境的变量绑定都丢失了。 |
|
然而,在subdialog的环境中,一般的语法、事件和变量的作用域规则也适用。激活的语法包括在该subdialog的文档和应用根文档中的<link>,<menu>和<form>元素的适当的语法,和解释器环境定义的默认语法。同样的,事件处理和变量绑定也是根据标准的作用域层次进行的。 |
|
从编程的角度看,subdialog的工作机制和子程序的工作机制是不一样的,因为它的调用和被调用的环境是相互独立的,subdialog不能访问调用它的dialog中的变量实例,而子程序取可以访问调用程序中的变量实例。类似的,subdialog在语言上不遵循事件渗透模式(event percolation model),而在java语言中,如果在某个方法中抛出事件,且该被调用的环境没有处理该事件,则该事件会自动的渗透到调用的环境中。在subdialog中抛出的事件交由subdialog中的事件处理取处理。这些事件处理要返回到调用的环境中只有通过显式的返回该事件。 |
|
<subdialog>元素的src或srcexpr属性指定了要调用的subdialog的URI(见RFC2396)。如果该URI是一个绝对或相对的URI,该URI可以包含一个查询串,则获取该URI并在目标文档中寻找该subdialog。如果<subdialog>元素指定了namelist属性,则该属性中的变量被加入到该URI的查询串中。 |
|
如果该URI只包含一个段,且没有指定namelist属性,则不获取任何URI,并在当前文档中寻找要调用的subdialog。 |
|
如果URI中有包含一个段,则该段指定了要调用的subdialog,如果没有包含段,则以目标文档的第一个dialog为要调用的subdialog。 |
|
如果该URI是非法的(即它指定的diaog或文档不存在),必须抛出一个error.badfetch事件。注意,对于那些在dialog或文档跳转中出现的错误,在什么范围内处理是依赖于平台的。 |
|
<subdialog>元素的属性有: |
name |
存放subdialog返回值的变量,他是一个ECMAScript Object,该对象的属性就是<return>元素的namelist属性中的变量名。 |
expr |
该form item变量的初始值,它默认为ECMAScript的undefined。如果给它赋一个初始值,则该form item就不会被访问,除非该form item变量被清零。 |
cond |
ECMAScript表达式。只有当其结果值为boolean true,该元素才被执行,否则不被执行。缺省时为true。 |
namelist |
要提交的变量名列表,默认是提交0个变量。如果指定了该属性,它可以包含多个变量,以空格隔开。在VoiceXML和ECMAScript中声明的变量都可以被提交。 |
src |
要调用的subdialog的URI。 |
srcexpr |
ECMAScript表达式,它的结果值为要调用的subdialog的URI。 |
method |
见5.3.8节。 |
enctype |
见5.3.8节。 |
fetchaudio |
见6.1节。它默认为<property>的fetchaudio的值。 |
fetchhint |
见6.1节。它默认为<property>的documentfetchhint的值。 |
fetchtimeout |
见6.1节。它默认为<property>的fetchtimeout的值。 |
maxage |
见6.1节。它默认为<property>的documentmaxage的值。 |
maxstale |
见6.1节。它默认为<property>的documentmaxstale的值。 |
|
表14:<subdialog>元素的属性 |
|
必须正确的指定属性src和srcexpr中的一个,否则,要抛出一个error.badfetch事件。 |
|
<subdialog>元素不但可以包含所有form item可包含的元素,还可以包含<param>元素。<subdialog>元素的<param>元素指定了要传给subdialog的参数,这些参数必须在subdialog中用<var>元素声明。试图用<param>元素给一个form item变量或未声明的变量赋值,会产生一个语义错误。当subdialog初始化时,它的变量按照文档顺序被依次初始化为<param>元素中相应的变量的值。在<param>元素的环境中,通过对它的属性expr求值来得到参数值。在这种情况下,<var>元素的expr属性被忽略。如果<var>元素声明的变量没有相应的<param>元素配对时,则它的expr属性值被作为该变量的默认值,或者该变量为undefined(如果该<var>元素没有指定expr属性)。 |
|
在下面的例子中,个人的生日用于验证他们的驾驶执照。<subdialog>元素的src指定了同一个文档中的另一个dialog作为subdialog,<param>元素用于传递生日给subdialog: |
|
<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.0" xmlns="http://www.w3.org/2001/vxml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3.org/2001/vxml
http://www.w3.org/TR/voicexml20/vxml.xsd">
<!-- form dialog that calls a subdialog -->
<form>
<subdialog name="result" src="#getdriverslicense">
<param name="birthday" expr="'2000-02-10'"/>.
<filled>
<submit next="http://myservice.example.com/cgi-bin/process"/>
</filled>
</subdialog>
</form>
<!-- subdialog to get drivers license -->
<form id="getdriverslicense">
<var name="birthday"/>
<field name="drivelicense">
<grammar src="http://grammarlib/drivegrammar.grxml"
type="application/srgs+xml"/>
<prompt> Please say your drivers license number. </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>
|
|
该例子返回了驾驶执照的值和用于表明执照是否非法的状态变量给调用的dialog。 |
|
该例子说明了使用<param>元素传递数据给subdialog的方便性,而不需要使用服务器端的脚本编程。下面这个例子使用了服务器端的脚本编程,它的效果和上面的例子是一样的: |
|
调用一个subdialog的form的文档 |
|
<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.0" xmlns="http://www.w3.org/2001/vxml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3.org/2001/vxml
http://www.w3.org/TR/voicexml20/vxml.xsd">
<form>
<field name="birthday">
<grammar type="application/srgs+xml" src="/grammars/date.grxml"/>.
What is your birthday?
</filled>
<subdialog name="result" src="/cgi-bin/getlib#getdriverslicense" namelist="birthday">
<filled>
<submit next="http://myservice.example.com/cgi-bin/process"/>
</filled>
</subdialog>
</form>
</vxml>
|
|
包含subdialog的文档(由/cgi-bin/getlib产生) |
|
<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.0" xmlns="http://www.w3.org/2001/vxml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3.org/2001/vxml
http://www.w3.org/TR/voicexml20/vxml.xsd">
<form id="getdriverslicense">
<var name="birthday" expr="'1980-02-10'"/>
<!-- Generated by server script -->.
<field name="drivelicense">
<grammar src="http://grammarlib/drivegrammar.grxml"
type="application/srgs+xml"/>
<prompt>
Please say your drivers license number.
</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在一个单独的文档中。它可在不同的应用中重用。它返回了状态、信用卡号和过期时间。如果得不到结果,返回状态值为“no_result”: |
|
<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.0" xmlns="http://www.w3.org/2001/vxml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3.org/2001/vxml
http://www.w3.org/TR/voicexml20/vxml.xsd">
<!-- Example of subdialog to collect credit card information. -->
<!-- file is at http://www.somedomain.example.com/ccn.vxml -->
<form id="getcredit">
<var name="status" expr="'no_result'"/>
<field name="creditcardnum">
<prompt>What is your credit card number?</prompt>.
<help>.
I am trying to collect your credit card information.
<reprompt/>
</help>
<nomatch>
<return namelist="status"/>
</nomatch>
<grammar src="ccn.grxml" type="application/srgs+xml"/>
</field>
<field name="expirydate">
<grammar type="application/srgs+xml" src="/grammars/date.grxml"/>
<prompt>What is the expiry date of this card?</prompt>
<help>
I am trying to collect the expiry date of the credit card number you provided.
<reprompt/>
</help>
<nomatch>
<return namelist="status"/>
</nomatch>
</field>
<block>
<assign name="status" expr="'result'"/>
<return namelist="status creditcardnum expirydate"/>
</block>
</form>
</vxml>
|
|
下面是一个应用,它包含有一个调用dialog。该应用通过混合主动式dialog获得软件名和操作系统名,然户调用subdialog要求用户输入信用卡信息: |
|
<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.0" xmlns="http://www.w3.org/2001/vxml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3.org/2001/vxml
http://www.w3.org/TR/voicexml20/vxml.xsd">
<!-- Example main program -->
<!-- http://www.somedomain.example.com/main.vxml -->
<!-- calls subdialog ccn.vxml -->
<!-- assume this gets defined by some dialog -->
<var name="username"/>
<form id="buysoftware">
<var name="ccn"/>
<var name="exp"/>
<grammar src="buysoftware.grxml" type="application/srgs+xml"/>.
<initial name="start">.
<prompt>
Please tell us the software product you wish to buy
and the operating system on which it must run.
</prompt>
<noinput>
<assign name="start" expr="true"/>
</noinput>
</initial>
<field name="product">
<prompt>Which software product would you like to buy?</prompt>
</field>
<field name="operatingsystem">
<prompt>Which operating system does this software need to run on?</prompt>
</field>
<subdialog name="cc_results" src="http://somedomain.example.com/ccn.vxml">
<filled>
<if cond="cc_results.status=='no_result'">
Sorry, your credit card information could not be
Obtained. This order is cancelled.
<exit/>
<else/>
<assign name="ccn" expr="cc_results.creditcardnum"/>
<assign name="exp" expr="cc_results.expirydate"/>
</if>
</filled>
</subdialog>
<block>
We will now process your order. Please hold.
<submit next="www.somedomain.example.com/process_order.asp"
namelist="username product operatingsystem ccn exp"/>
</block>
</form>
</vxml>
|
|
五、OBJECT |
|
在VoiceXML应用程序中通过<object>元素,VoiceXML的执行平台可以扩展依赖于平台的一些功能。在初始化和执行期间,<object>元素直接使用他自己的内容(例如它的<param>子元素)。因此,不能认为<object>元素的内容是可有可无的。注意,和其他的field item一样,<object>元素也有<prompt>元素和<catch>元素,它也可以有<filled>操作。 |
|
例如,能像上面的例子一样访问一个依赖于平台的用来收集信用卡信息的object。 |
|
<object name="debit" classid="method://credit_card/gather_and_debit"
data="http://www.recordings.example.com/prompts/credit/jesse.jar">
<param name="amount" expr="document.amt"/>
<param name="vendor" expr="vendor_num"/>
</object>
|
|
在这个例子中,当object被调用时,<param>元素用于传递参数。<object>元素执行后返回一个ECMAScript Object作为该fom item变量的值。下面的例子中的<block>元素引用了object返回的值。 |
|
<block>
<prompt>
The card type is <value expr="debit.card"/>.
</prompt>
<prompt>
The card number is <value expr="debit.card_no"/>.
</prompt>
<prompt>
The expiration date is <value expr="debit.expiry_date"/>.
</prompt>
<prompt>
The approval code is <value expr="debit.approval_code"/>.
</prompt>
<prompt>
The confirmation number is <value expr="debit.conf_no"/>.
</prompt>
</block>
|
|
在下面这个例子中,假设平台有一个object,该object可以让用户通过电话键盘输入任意的文本信息。 |
|
<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.0" xmlns="http://www.w3.org/2001/vxml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3.org/2001/vxml
http://www.w3.org/TR/voicexml20/vxml.xsd">
<form id="gather_pager_message">
<object name="message" classid="builtin://keypad_text_input">
<prompt>
Enter your message by pressing your keypad once
per letter. For a space, enter star. To end the
message, press the pound sign.
</prompt>
</object>
<block>
<assign name="document.pager_message" expr="message.text"/>
<goto next="#confirm_pager_message"/>
</block>
</form>
</vxml>
|
|
用户首先听到一些提示语,然后按键输入信息。在<block>元素中把用户输入的信息赋给变量document.pager_message。 |
|
<object>元素的属性: |
name |
当该<object>元素执行时,该form item变量被置为一个ECMAScript object类型的值。 |
expr |
该form item变量的初始值,默认为ECMAScript的undefined。如果它的值不为ECMAScript的undefined,则它将不会被访问,除非该form item变量被清零。 |
cond |
ECMAScript 表达式。只有当其结果值为boolean true,该form item块才被执行,否则不被访问。缺省时为true。 |
classid |
一个URI,它指定了要执行的object的位置。该URI的拼写规则是依赖于平台的。 |
codebase |
基路径,用于解析classid、data和archive属性指定的相对URI。它默认为当前文档的基础URI。 |
codetype |
下载classid指定的object时期望的数据类型。如果没有指定,默认为属性type的值。 |
data |
指定object数据的位置的URI。如果它是一个相对的URI,则以codebase属性指定的值为基路径。 |
type |
Data属性指定的数据的类型。 |
archive |
一组和该object有关的档案的URI,由空格隔开。这些档案包含了classid和data属性指定的数据。如果这些URI是一个相对的URI,则以codebase属性指定的值为基路径。 |
fetchhint |
见6.1节。它默认为<property>的documentfetchhint的值。 |
fetchtimeout |
见6.1节。它默认为<property>的fetchtimeout的值。 |
maxage |
见6.1节。它默认为<property>的documentmaxage的值。 |
maxstale |
见6.1节。它默认为<property>的documentmaxstale的值。 |
|
表15:<object>元素的属性 |
|
没有必要提供依赖于平台的object,如果基于特定平台的object不支持,将抛出error.unsupported.objectname事件。如果做到了这一点,就可以认为是支持<object>元素了。 |
|
Object自己负责检查它收到的参数名或参数值是否非法。如果是非法的话,<object>元素抛出一个错误。该错误可以是依赖于object的,也可以是5.2.6节中列出的标准错误之一。 |
|
六、RECORD |
|
<record>元素是一个input item,用于收集用户的录音。该input item变量保存了录制的音频的引用。它能被播放(使用<audio>元素的expr属性)或者提交给服务器,如下面的例子: |
|
<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.0" xmlns="http://www.w3.org/2001/vxml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3.org/2001/vxml
http://www.w3.org/TR/voicexml20/vxml.xsd">
<form>
<property name="bargein" value="true"/>
<block>
<prompt>
Riley is not available to take your call.
</prompt>
</block>
<record name="msg" beep="true" maxtime="10s" finalsilence="4000m
dtmfterm="true" type="audio/x-wav">
<prompt timeout="5s">
Record a message after the beep.
</prompt>
<noinput>
I didn't hear anything, please try again.
</noinput>
</record>
<field name="confirm">
<grammar type="application/srgs+xml" src="/grammars/boolean.grxml"/>
<prompt>
Your message is <audio expr="msg"/>.
</prompt>
<prompt>
To keep it, say yes. To discard it, say no.
</prompt>
<filled>
<if cond="confirm">
<submit next="save_message.pl" enctype="multipart/form-data"
method="post" namelist="msg"/>
</if>
<clear/>
</filled>
</field>
</form>
</vxml>
|
|
它先给用户播放<record>元素的提示语,然后进行录音。如果遇到如下的情况之一,就会终止录音:达到final silence的条件,或者有DTMF按键输入,或者达到最大的录音时间,或者用户挂机。该录音被回放,如果用户满意,就用HTTP POST方法把它提交给服务器存储。注意:和其他的input item一样,<record>元素也有<grammar>、<prompt>和<catch>元素。它也可以有<filled>操作。 |
|
|
图7: 提示语、音频录制和DTMF输入的时间选择 |
|
当用户在录音时挂机,录音终止并抛出connection.disconnect.hangup事件。然而,在用户挂机之前所录下来的音频还是可用的,可通过<record>元素的form item变量引用。即使,在挂机之后,应用程序,例如下面这个简单的语音邮件服务,还是能把该音频数据返回给服务器: |
|
<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.0" xmlns="http://www.w3.org/2001/vxml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3.org/2001/vxml
http://www.w3.org/TR/voicexml20/vxml.xsd">
<form>
<record name="msg" beep="true" maxtime="10s" finalsilence="4000ms"
dtmfterm="true" type="audio/x-wav">
<prompt timeout="5s">
Record a message after the beep.
</prompt>
<noinput>
I didn't hear anything, please try again.
</noinput>
<catch event="connection.disconnect.hangup">
<submit next="./voicemail_server.asp"/>
</catch>
</record>
</form>
</vxml>
|
|
在播放完所有的提示语之后(如果有定义“beep”声的话,也包括“beep”声),录音开始。作为一种优化,平台可以在用户开始说话的同时开始录音。 |
|
Timeout时间间隔在开始播放提示语时即生效,它的持续时间由timeout property决定。如果在开始录音之前就已经超过了timeout的时间间隔,则抛出noinput事件。 |
|
Maxtime时间间隔在开始录音时生效,它的持续时间取决于该form item的maxtime属性。如果在录音结束之前就超过maxtime时间间隔,则录音终止,且该form item的maxtime影子变量被置为true。 |
|
当抛出一个事件,或者有DTMF(语音)输入匹配了一个激活的语法,或者超过了maxtime时间间隔,录音终止。最为一个最佳的选择,平台可以在达到一个静音的时间间隔(由finalsilence属性设置)后终止录音,该静音的时间间隔表示用户已经停止输入了。 |
|
如果在执行<record>元素时,没有收集到任何音频,则该form item变量保持unfilled。例如,当在播放提示语的时候接收到DTMF或语音输入,或达到timeout时间间隔(如果在播放提示语的时候,开发者想要一个输入来初始化录音,则<prompt>元素应紧接着放在<field>元素之后,且该<prompt>元素的timeout属性值为0),就会出现这种情况。 |
|
<record>元素包含了dtmfterm属性,当它的值为true时,它的作用等同于定义了一个本地的DTMF语法,该语法匹配了所有的DTMF输入。 |
|
任何DTMF按键匹配了一个激活的语法就会终止录音。DTMF按键没有匹配一个激活的语法就会被忽略(因此不会终止录音,也就是不会影响到录音)且它的信号可以被平台清除掉(可选的)。 |
|
平台在录音的时候支持语音语法,这是可选的。如果平台在录音的同时支持语音识别,则录音会被匹配一个激活的语音语法的语音输入终止。终止录音的语音输入可通过application.lastresult$和该item的utterance和confidence影子变量访问。用于识别终止录音的语音输入的音频是不可用的,且它不是录音的一部分。 |
|
如果终止录音时匹配的语法(DTMF或语音)是一个本地语法,该录音存放在该form item变量中,否则该form item变量为unfilled且返回到FIA。无论是哪一种情况,application.lastresult$和该form item的影子变量都会被赋值。 |
|
注意:在这种情况下虽然该form item变量没有被录音所填充,然而匹配一个非本地的语法可以导致给该form item变量赋某种值(详见3.1.6节)。 |
|
<record>元素的属性有: |
name |
该input item变量保存了所录制的音频。注意,各个平台实现该变量的方式可以是不同的(虽然该技术说明书中要求所有的平台都必须在<audio>元素和<submit>元素中支持该变量的行为)值。 |
expr |
该form item变量的初始值,它默认为ECMAScript的undefined 。如果给它赋一个初始值,则该form item就不会被访问,除非该form item变量被清零。 |
cond |
ECMAScript表达式。只有当其结果值为boolean true,该元素才被执行,否则不被执行。缺省时为 true。 |
modal |
如果该属性值为true(默认值),在录音时,所有非本地的语音和DTMF语法都会失效。若为false,则是激活的。 |
beep |
当为true时,录音前有“嘟”音提示。缺省值为 false。 |
maxtime |
最长录音时间。它是一个Time Designation (见6.5节)。默认为一个依赖于平台的值。 |
finalsilence |
表示录音结束的静音输入时间。它是一个Time Designation (见6.5节)。默认为一个依赖于平台的值。 |
dtmfterm |
如果该属性值为true,任何没有匹配一个激活语法的DTMF按键被认为匹配了一个激活的(anonymous)本地DTMF语法。默认值为true。 |
type |
表示所录制的音频的媒体格式。平台必须支持附录E中指定的声音文件格式(也可以支持其他的格式)。默认为一个平台指定的格式,该格式应该是不许支持的格式之一。 |
|
表16:<record>元素的属性 |
|
在录音之后,<record>元素的影子变量也被赋值: |
|
下表是<field>元素的影子变量(shadow variables),该<field>的form item 变量名为name。影子变量utterance、 inputmode 和 interpretation的值必须和application.lastresult$ (详见5.1.5节)中相应变量的值一样。 |
name$.duration |
录音的持续时间,单位为毫秒。 |
name$.size |
录音的大小,单位为byte。 |
name$.termchar |
如果该form item的dtmfterm属性值为true,且用户通过DTMF按键终止录音,则该影子变量的值为用户的按键(例如“#”),否则它的值为undefined。 |
name$.maxtime |
如果是因为达到最大录音时间而终止录音,则该变量值为true,否则为false。 |
name$.utterance |
如果是因为用户在录音时的语音输入匹配了一个语法而终止了录音,则该变量值为被匹配的字符串,否则它的值为undefined。 |
name$.confidence |
当用户在录音时的语音输入匹配了一个语法而终止了录音,该变量值为被匹配的字符串的confidence级别(0.0-1.0)否则值为undefined。 |
|
表17:<record>元素的影子变量 |
|
七、TRANSFER |
|
<transfer>元素引导VoiceXML解释器将主叫方连接到诸如电话、或其它语音应用程序。在转接过程中,当前的解释器进程处于等待状态。 |
|
有各种转接方式,如:“bridge”、“blind”。还有基于网络的转接,如“switchhook transfer”。在VoiceXML解释器中,只支持Bridge和Blind两种方式的转接类型。其它的依赖于指定的平台和网络特性,以及配置,这些内容超出了本规范的范围。 |
|
<Transfer>元素是可选的。支持<Transfer>的平台应支持Bridge和Blind两种Transfer类型。支持Bridge transfer的平台在转接通话过程中,对DTMF接收和语音识别的支持是可选的。 |
|
<Transfer>元素的属性: |
name |
在bridge方式下,保存转接通话完成后的结果值。在blind方式下,这个变量的值是undefined。 |
expr |
Form item的初始值。缺省是ECMAScript undefined。如果初始化到一个值,这个元素将不被访问。只有当这个Item的值被清除后才能被访问。 |
cond |
这是一个表达式,只有当它是true时,这个才form item可以被访问。 |
dest |
目标的URI地址(如:电话、IP电话地址)。VoiceXML平台必须支持tel:URL语法格式(这种语法格式在[RFC2806]中描述),也可以支持其它基于URI地址格式。 |
destexpr |
ECMAScript表达式,它生成URI地址。 |
bridge |
决定平台在<transfer>执行后,是否依然监控主叫方和被叫方。
true | Bridge transfer:VoiceXML解释器一直处于等待状态,直到Transfer从转接通话状态下退出。如果因为挂机或网络的原因而线路中断,会抛出一个Connection.disconnect.hangup事件。如果通话因为其它原因而中断,中断原因会写在元素的属性里。 | false | Blind transfer(default):VoiceXML解释器在完成转接后,不再监控转接过程,也不再在元素的名字属性中报告挂断结果,而是立即抛出一个connection.disconnect.transfer事件。 |
|
connectiontimeout |
在电话转接过程中,VoiceXML解释器在noanswer事件出现前能够等待的时间。这一属性只有在bridge是true时才有效。在缺省情况下,这个值是平台指定的。 |
maxtime |
允许通话的最大时间。0表示没有时间限制。只有当bridge是true时才有效。缺省情况下,这个值是0。 |
transferaudio |
在转接而对方没有应答前,用来放音的语音URI地址。如果语音没有取到,错误将被忽略,转接继续进行。 |
aai |
应用程序之间用来交换的串信息。它可以在进程变量session.connection.aai中得到。aai数据的传输依赖于网关或ISDN、SIP。数据发送到远端是否成功,并没有报告。虽然所有的平台必须支持aai属性,平台不一定非要发送aai和接收aai数据。如果平台不能接收aai数据,必须将session.connection.aai变量置为ECMAScript undefined。 |
destexpr |
ECMAScript表达式,它生成URI地址。 |
|
表18:<transfer>元素的属性 |
|
“dest”和“destexpr”必须指定其一。如果两者都没有指定,error.badfetch事件就会抛出。“aai”和“aai”事件也必须指定其一,不然,error.badfetch事件也产生。 |
|
<一>、Blind Transfer |
|
Blind Transfer是用来将主、被叫联结起来的操作。在元素<transfer>前和在元素<transfer>内的<prompt>语句都会在转接开始前依次播放,而且同样具有bargein属性。 |
|
|
图8: 在Blind Transfer下的联结: <transfer bridge="false"> |
|
因为在转接过程中声音文件不能播放给主叫,所以transferaudio属性指定的语音文件在转接过程中被忽略。不管转接是否成功,VoiceXML语音平台不能再获得对呼入和转接电话的控制权。 |
|
转接的状态不能得到。例如,不可能知道被叫是不是忙,这次呼叫是否成功等等。然而,有些错误是可以得到的,如主叫无权呼叫被叫方或者目标地址URI是错误的。 |
|
一旦转接开始,VoiceXML解释器与电话进程脱离联系,平台将抛出一个connection.disconnect.transfer错误,解释器还会继续运行。 |
Action |
Form item变量的值 |
事件或错误 |
原因 |
转接开始 |
undefined |
connection.disconnect.transfer |
转接进行,但不会返回。 |
转接结束 |
unknown |
|
转接结束,但结果未知。 |
|
表19:Blind Transfer Outcomes |
|
<二>、Bridge Transfer |
|
对于Bridge Transfer,主叫和被叫是以全双工方式进行的。 |
|
|
图9: bridge transfer下的电话转接:<transfer bridge="true"> |
|
在<transfer>语句前和在<transfer>语句内的提示语音会依次播放,bargein也是有效的。 |
|
1、Listening for user input during a transfer |
|
在<transfer>元素中可以指定一个或多个语法,这样在通话过程中,就可以监视用户的输入而中断转接。 |
|
可以指定两种输入: |
|
·DTMF输入; |
|
·语音输入。 |
|
如果用户的输入匹配了所指定的语法,VoiceXML解释器将继续按照VoiceXML文本所指定的操作运行。如果没有指定语法文件,在转接过程中,将不监控用户的输入。Bargein属性同样适用于元素<transfer>前和元素<transfer>内的语音提示。此时,外呼开始;Transferaudio所指定的语音播放开始;语法文件所指定的DTMF或语音识别成为Bargein的唯一方式(直到对远端的联结建立)。因此bargeintype被忽略。转接元素是模式的,因为在其作用域之外的语法没有激活。 |
|
平台解释器没有监控被叫的输入。 |
|
2、Handling caller, callee, or network disconnections |
|
当试图去联结被叫,平台监控呼叫进程指示器(in bound或out of bound,依赖于特殊的联结类型和协议)。在成功的转接期间,平台监控(out of band)电话事件,如电话的挂机事件。 |
|
如果被叫挂断,主叫重新继续它的任务。如果主叫挂断,平台挂断被叫。主叫或被叫挂断或两者同时挂断都不影响平台解释器的运行。 |
|
在转接到被叫前,可能的结果如下: |
Action |
Form item变量的值 |
事件或错误 |
原因 |
主叫挂断 |
|
connection.disconnect.hangup |
主叫挂机。 |
被叫忙 |
busy |
|
被叫忙。 |
网络忙 |
Network_busy |
|
中间网络不应答。 |
被叫没有应答 |
noanswer |
|
在connecttimeout属性指定的时间内没有应答。 |
---- |
unknown |
|
转接结束但结果未知。 |
|
表20:Bridged Transfer Outcomes Prior to Connection Being Established |
|
转接后可能的结果: |
Action |
Form item变量的值 |
事件或错误 |
原因 |
主叫挂断 |
|
connection.disconnect.hangup |
主叫挂断。 |
主叫挂断 |
near_end_disconnect |
|
主叫通过DTMF或语音强迫被叫挂机。 |
平台挂断被叫 |
maxtime_disconnect |
|
因为最大的通话时间到达,平台挂断被叫。 |
网络挂断 |
network_disconnect |
|
网络挂断被叫。 |
被叫挂断 |
far_end_disconnect |
|
被叫挂断。 |
---- |
unknown |
|
转接因未知原因而中断。 |
|
表21:Bridged Transfer Outcomes After Connection Established |
|
在转接完成后,元素<transfer>的影子变量有如下ECAMScript属性: |
name$.duration |
转接通话时间(浮点值),如果在被叫回答前就被挂断,此值为零。 |
name$.inputmode |
中断转接过程的输入模式(voice或dtmf)。 |
name$.utterance |
如果转接因语音而中断,此值中应是说出的文本;否则没有定义。 |
|
表22:<transfer>元素的影子变量 |
|
3、Audio during bridge transfer attempt |
|
在Bridge transfer过程中,也许要对主叫播放语音。例如一个广告(“Buy Joe's Spicy Shrimp Sauce”)或一个信息(“Your call is very important to us; please wait while we connect you to the next available agent.”)。这样便可以对呼叫进程中振铃、忙等情况而出现的静音起一个补偿作用。 |
|
当远端的应答出现时,Transferaudio的播放中止。远端的应答不会永远出现的,因为远端交换机可以播放语音而不回答呼叫(这些语音包括一个特殊的音调、忙音、网络忙音、或者一个提示联结不能进行的录音)。 |
|
如果一个语音播放的时间短于转接到远端的所需的时间,主叫也许会听到静音、平台所指定的语音、或者是呼叫进行过程中的信息。具体是何种语音依赖于不同的平台。 |
|
<三>、Transfer Errors and Events |
|
事件 |
原因 |
转接类型 |
connection.disconnect.hangup |
主叫挂机。 |
bridge |
connection.disconnect.transfer |
将主叫转接到另一方,而且返回。 |
blind |
|
表23:Events Thrown During Transfer |
|
如果transfer不能进行,下列错误将会抛出: |
错误 |
原因 |
转接类型 |
error.connection.noauthorization |
主叫不允许呼叫目标。 |
Blind和Bridge |
error.connection.baddestination |
目标URI错误。 |
Blind和Bridge |
error.connection.noroute |
平台不能对目标呼叫 |
bridge |
error.connection.noresource |
平台不能分配资源而不能呼叫。 |
bridge |
error.connection.protocol.nnn |
协议栈在联结中出现一个例外,此例外不能对应于任何一个error.connection事件。 |
bridge |
error.unsupported.transfer.blind |
平台不能支持Blind转接。 |
blind |
error.unsupported.transfer.bridge |
平台不能支持Bridge转接。 |
bridge |
error.unsupported.uri |
平台不能支持用到的URI格式,指定的变量_message(Section 5.2.2)将包含串“The URI x is not a supported URI format”,x是<transfer>的dest或destexpr属性。 |
Blind和Bridge |
|
表24:Transfer Attempt Error Events |
|
<四>、Example |
|
下面的例子试图将主叫转接到另一方,并等待通话的结束。语音提示可能在元素<transfer>前或内部。这也许用来通知主叫,发生了什么事情。这种通知通常是“请等待,正在转接呼叫”。在<block>、<transfer>中的<prompt>元素,在执行转接前,依次播放。语音队列开始播放,呼叫便开始。在缺省情况下,主叫联结到外呼的电话通道。“transferaudio”属性指定对主叫播放的语音文件,它会在远端应答时停止播放。如果语音的长度大于联结所需的时间,只要远端应答,也会停止播放。 |
|
|
图10:Sequence and timing during an example of a bridge transfer |
|
<?xml version="1.0" encoding="UTF-8"?>
<vxml version="2.0" xmlns="http://www.w3.org/2001/vxml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3.org/2001/vxml
http://www.w3.org/TR/voicexml20/vxml.xsd">
<form id="xfer">
<var name="mydur" expr="0"/>
<block>
<!-- queued and played before starting the transfer -->
<prompt>
Calling Riley. Please wait.
</prompt>
</block>
<!-- Play music while attempting to connect to far-end -->
<!-- "hotword" bargeintype during transferaudio only -->
<!-- Wait up to 60 seconds for the far end to answer -->
<transfer name="mycall" dest="tel:+1-555-123-4567"
transferaudio="music.wav" connecttimeout="60s" bridge="true">
<submit next="./voicemail_server.asp"/>
<!-- queued and played before starting the transfer -->
<!-- bargein properties apply during this prompt -->
<prompt>
Say cancel to disconnect this call at any time.
</prompt>
<!-- specify an external grammar to listen for "cancel" command -->
<grammar src="cancel.grxml" type="application/srgs+xml"/>
<filled>
<assign name="mydur" expr="mycall$.duration"/>
<if cond="mycall == 'busy'">
<prompt>
Riley's line is busy. Please call again later.
</prompt>
<elseif cond="mycall == 'noanswer'"/>
<prompt>
Riley can't answer the phone now. Please call again later.
</prompt>
</if>
</filled>
</transfer>
<!-- submit call statistics to server -->
<block>
<submit namelist="mycall mydur" next="/cgi-bin/report"/>
</block>
</form>
</vxml>
|
第四节 Filled | | | <filled>元素指定了当一个或多个input item被填充后要执行的操作。它可以出现在两个地方:作为<form>元素的子元素,或者作为input item的子元素。 | | 如果作为<form>元素的子元素,当一个或多个input item的组合被填充后,<filled>元素用于执行一些操作。下面的例子中的<filled>元素用于交叉检查以确保“start_city” <field>和“end_city”<field>的识别结果不一样: | | <?xml version="1.0" encoding="UTF-8"?> <vxml version="2.0" xmlns="http://www.w3.org/2001/vxml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2001/vxml http://www.w3.org/TR/voicexml20/vxml.xsd"> <form id="get_starting_and_ending_cities"> <field name="start_city"> <grammar src="http://www.grammars.example.com/voicexml/city.grxml" type="application/srgs+xml"/> <prompt>What is the starting city?</prompt> </field> <field name="end_city"> <grammar src="http://www.grammars.example.com/voicexml/city.grxml" type="application/srgs+xml"/> <prompt>What is the ending city?</prompt> </field> <filled mode="all" namelist="start_city end_city"> <if cond="start_city == end_city"> <prompt>You can't fly from and to the same city.</prompt> <clear/> </if> </filled> </form> </vxml> | | 如果<filled>作为一个input item的子元素出现,它指定了当该input item被填充后要执行的操作: | | <?xml version="1.0" encoding="UTF-8"?> <vxml version="2.0" xmlns="http://www.w3.org/2001/vxml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2001/vxml http://www.w3.org/TR/voicexml20/vxml.xsd"> <form id="get_city"> <field name="city"> <grammar type="application/srgs+xml" src="http://www.ship-it.example.com/grammars/served_cities.grxml"/> <prompt>What is the city?</prompt> <filled> <if cond="city == 'Novosibirsk'"> <prompt>Note, Novosibirsk service ends next year.</prompt> </if> </filled> </field> </form> </vxml> | | 每次收集用户的输入后,该输入中提及的input item都被做了标记,然后解释器根据每个<filled>元素在文档中的顺序(input item中的<filled>元素和<form>中的<filled>元素优先权一样)依次访问它们。那些匹配该utterance的<filled>元素被依次执行,除非已经没有<filled>元素,或者出现控制跳转,或者抛出事件。 | | <filled>元素的属性有: | mode | 值为all(默认)或any。如果值为any,当任意一个指定的input item被用户最近一次的输入填充后,就执行该<filled>元素的操作。如果值为all,当所有提到的input item被填充,且用户最后一次输入填充了至少一个input item,就执行该<filled>元素的操作。在input item中的<filled>元素不能指定该属性。 | namelist | 要触发的input item。对于<form>元素中的<filled>元素,该属性默认为该form中所有的input item变量(包括显式和隐式)。一个input item中的<filled>元素则不能指定该属性,这种情况下,namelist属性值实际上就是该input item的名称。注意control item不能出现在该属性中。 |
| 表25:<filled>元素的属性 |
第五节 Links | | | <link>元素可以有一个或几个语法,语法的作用域为包含该<link>元素的元素。该包含<link>元素的元素的scope属性不会影响<link>元素中语法的作用域。<link>元素被包含于一个<form>元素中,该<form>元素的scope属性为document,该<link>元素语法的作用域在该form内,而不是整个文档。<link>元素中的<grammar>元素是不允许指定scope属性的。当这些语法中的一个被匹配,<link>元素被激活,要么跳转到一个新的文档或dialog(如<goto>),要么抛出一个事件(如<throw>)。 | | 例如,当用户说“books”或按“2”时,<link>元素被激活: | | <link next="http://www.voicexml.org/books/main.vxml"> <grammar mode="voice" version="1.0" root="root"> <rule id="root" scope="public"> <one-of> <item>books</item> <item>VoiceXML books</item> <one-of> </rule> </grammar> <grammar mode="dtmf" version="1.0" root="r2"> <rule id="r2" scope="public"> 2 </rule> </grammar> </link> | | 当语法被匹配时,下面的<link>元素动态的决定要跳转到当前文档的哪一个dialog: | | <link expr="'#' + document.helpstate"> <grammar mode="voice" version="1.0" root="root"> <rule id="root" scope="public"> help </rule> </grammar> </link> | | <link>元素可以是<vxml>和<form>的子元素,或form item<field>和<initial>的子元素。作为<vxml>的子元素,<link>元素的语法在整个文档中都是激活的;作为<form>的子元素,<link>元素的语法在该form中是激活的;如果应用根文档中有一个文档级的<link>元素,它的语法在该应用所有被加载的文档中都是激活的。 | | 如果在一个form item中执行,且该form item的modal属性为true,则form级或文档级的<link>元素的语法是不激活的。 | | 也可以定义一个<link>元素,当语法匹配时抛出一个事件,而不是跳转到一个新的文档或dialog,该事件是在当前执行的地方被抛出,而不是在定义<link>元素的地方被抛出。例如,当用户的输入匹配了<link>元素的语法或用户按键输入了"2",在用户正在访问的form item的地方抛出了help事件,由该form item的作用域内相应的<catch>元素处理(详见5.2.4节)。 | | <link dtmf="2" event="help"> <grammar mode="voice" version="1.0" root="r5"> <rule id="r5" scope="public"> <one-of> <item>arrgh</item> <item>alas all is lost</item> <item>fie ye froward machine</item> <item>I don't get it</item> <one-of> </rule> </grammar> </link> | | 当匹配了<link>元素中的语法时,application.lastresult$也被赋值,这样才能允许呼叫流程在这个实际的语义结果的基础上往下走。在5.1.5中有一个例子。 | | 从概念上讲,可以认为<link>元素由两部分组成:条件和操作。“条件”就是<link>元素的内容,即它的语法,只有语法被匹配了,才能激活。“操作”由该元素的属性指定,即要跳转到哪里或抛出哪个事件。“条件”是静态地解决/求值的,而“操作”则是动态地解决/求值的。这意味着: | | 1、该<link>元素的内容中的任何URI都是被静态地求值的,即根据定义了<link>元素的文档的基本URI求值(详见1.5.1节的xml:base)。 | | 2、<link>元素属性中的任何URI都是被动态的求值的,即根据语法被匹配时正在执行的文档的基本URI求值。 | | 3、<link>元素的属性中的任何ECMAScript表达式都是被动态地求值的,即在语法被匹配时的作用域内和执行的环境中求值的。 | | <link>元素的属性有: | next | 要跳转到的URI,该URI是一个文档(也许有段标识符指定一个起始的dialog)或当前文档的一个dialog。 | expr | 和next属性一样,只不过该URI是根据给定的ECMAScript表达式动态地求值的。 | event | 当用户匹配了<link>元素中的一个语法时要抛出的事件。 | eventexpr | 一个ECMAScript表达式,它的结果值为当用户匹配了<link>元素中的一个语法时要抛出的事件。 | message | 描述事件产生原因的文本信息。 | messageexpr | 一个ECMAScript表达式,它的结果值为描述事件产生原因的文本信息。 | dtmf | 该<link>元素的DTMF序列,它的作用等同于一个简单的DTMF语法,和应用于该序列识别的DTMF<property>。它和DTMF语法不同的是,它的空格是不起作用的:dtmf=“123#”跟dtmf=“1 2 3 #”的效果是一样的。该属性能和其他的<grammar>同时使用。当用户的输入匹配了<link>元素中的一个语法或DTMF序列,该<link>元素被 激活。 | fetchaudio | 见6.1节。它默认为fetchaudio<property>的值。 | fetchhint | 见6.1节。它默认为documentfetchhint<property>的值。 | fetchtimeout | 见6.1节。它默认为fetchtimeout<property>的值。 | maxage | 见6.1节。它默认为documentmaxage<property>的值。 | maxstale | 见6.1节。它默认为documentmaxstale<property>的值。 |
| 表26:<link>元素的属性 | | 必须正确的指定属性“next”,“expr”,“event”或“eventexpr”中的一个,否则会抛出一个error.badfetch事件。必须正确的指定属性“message”或“messageexpr”中的一个,否则会抛出一个error.badfetch事件。 |
|
|
|
|
|
|