铁观音

C++编程宝典

   ::  ::  ::  ::  :: 管理 ::
  1 随笔 :: 19 文章 :: 0 评论 :: 0 Trackbacks
第二章  Dialog的结构
 
第一节 Forms  
 
    form是VoiceXML文档的主要组成部分,它包括以下几个部分:
      1、一组form item,即在FIA(form interpretation algorithm)的主循环被访问的一些元素。Form item可细分为input item和control item,input item可由用户填充,而control item不能;
      2、非form item(non-form item)变量的声明;
      3、事件处理;
      4、填充后(filled)的操作,也就是当某些input item的组合被赋值后要执行的程序逻辑模块。
    Form元素的属性:
id Form的名字。如果有指定的话,这个form就可以在该文档内被引用,或者在别的文档中引用它。例如,<form id="weather">,<goto next="#weather">。
scope 该form语法的默认作用域(scope)。如果它的值为dialog,则该form语法只是在这个form里是激活的;如果它的值为document,则该form语法在这个文档的任何对话中都是激活的;如果该文档为应用根文档,则该form语法在这个应用的任何文档的任何dialog中都是激活的。注意,单独的form的语法作用域的优先权高于默认的语法作用域。例如在非根文档的某个form默认的作用域为dialog,且有一个form语法的作用域为document,则该语法在这个文档的任何对话中都是激活的。
表3:<form>元素的属性
    这一节描述了关于form的一些概念,并给出了它们的一些操作的具体例子。
 
一、Form的解释
    form由内置的FIA解释。FIA有一个主循环用来重复选定一个form item并访问它。被选定的form item是在文档顺序中第一个警戒条件不满足的form item。例如,field的默认警戒条件检测看该field的form item变量是否有值。因此,如果一个简单的form只包含了几个field,则每个field会顺序地提示给用户。
    解释一个form item一般包括以下步骤:
      1、选定并播放一个或多个prompt;
      2、收集用户的输入,或填充一个或多个input item的响应,或一些事件的抛出(例如help);
      3、解释属于最新的input item的填充的<filled>操作。
    FIA终止于解释一个控制语句的跳转(例如用<goto>元素到另一个对话或文档,或者一个<submit>元素把数据提交到文档服务器)。当再没有符合条件的form item可以被选定时,FIA也随着一个隐式的<exit>而中止。
    关于FIA更详细的说明见2.1.6节。
 
二、Form Items
    form item就是在FIA的主循环中能够被访问的元素。Input item控制FIA为特定的元素收集信息。当FIA选定一个control item时,该control item可以包含一个要执行的代码块,或告诉FIA开始为混合主动式的form的提示和收集进行初始化。
 
    <一>、Input Items
    input item指定了得到用户输入的input item变量。它有一些提示,告诉用户要说或者键入什么;还有定义允许的输入的语法;还有处理一些由此产生的事件的事件处理。Input item也可以有<filled>元素,它定义了input item变量被填充以后要进行的操作。Input item有以下几个:
<field> 它的值是通过ASR或DTMF语法获得的。
<record> 它的值是用户录音的一段音频。例如,<record>元素可以用来收集语音邮件的语音信息。
<transfer> 它把用户转接到另一个电话号码。如果该转接返回控制,则把该转接结果的状态赋值给它的变量。
<object> 它通过一些参数调用依赖于平台的object,该object是一个ECMAScript Object。平台的object可以是一个内置的dialog,比如说用来收集信用卡信息的dialog。也可以是用特定的DTMF文本方法收集文本消息的dialog。虽然当依赖于平台的object不被平台支持时,要抛出error.unsupported.objectname事件来处理<object>元素(专门的事件变量“_message”提供了更详细的错误信息,详见5.2.2节),但是对于这些依赖于平台的object的执行却是没有任何限制的。
<subdialog> <subdialog>有点像函数调用。它调用同一文档中的另一个dialog,或者调用另一个文档。它返回的是一个ECMAScript Object。
表4:Input Items
 
    <二>、Control Items
    control item有两种:
<block> 它包含一些程序语句的序列,这些程序语句是用于提示和计算的,不是用于收集输入的。<block>有一个form item变量(通常是隐含的),在它被解释之前,该变量被置为true。
<initial> 该元素用于在混合主动式的form里控制最初的交互。它应该提示用户说一些话来匹配一个form级别的语法。在<initial>元素的执行中,当至少有一个input item变量被识别结果所填充时,<initial>元素的form item变量变为true,从而把它置为不是FIA可选定的。
表5:Control Items
 
三、Form Item变量和条件
    每个form item都有一个和它相关的form item变量,当进入该form时,它的默认值为undefined。Input item的form item变量包含了解释该form item的结果。Input item的form item变量也称为input item变量(Input item variable),它保存了从用户那里收集到的值。Input item变量可以用name属性给它命名;或让它匿名,此时会产生一个内部名称。
    每个form item也有一个警戒条件,它决定该form item是否能够被FIA选定。默认的警戒条件只是检测该form item是否有非undefined的值,如果有,该form item就不会被访问。
    通常,input item都会有名称,control item都没有名称;form item变量都没有被赋初始值,且没有指定附加的警戒条件。但有些时候需要更精确地控制。如:form可以在开始的时候给一个form item 变量赋初始值来跳过相应的field的执行,然后清零(如用<clear>元素)并强制该field重新被选定;另一个field可以有一个警戒条件,只有当该field没有被选定过,且其他两个field已经被填充时才激活它;或只有当某个条件为true时,<block>才能执行。这样一来,哪些form item会被FIA选定并执行的顺序可以得到更好的控制。然而,通常很多对话都可以不用这么复杂。
    总的来说,所有的form item都有如下的属性:
name 该form item变量的名称,作用域为dialog。它保存了该form item的值。
expr 给form item变量赋初始值,默认的初始值为ECMAScript 的undefined 。如果有初始值,则该form item不会被执行,除非该form item变量被清零。
cond 它是一个表达式的值,如果缺省,默认值为true。如果是在<initial>元素里,它用来检测是否有input item被填充了。
表6:Form Item共有的属性
 
四、Directed Forms
    最简单、最普通的form类型是,在computer-directed交互中,该form的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 id="weather_info">
         <block>Welcome to the weather information service.</block>
         <field name="state">
           <prompt>What state?</prompt>
           <grammar src="state.grxml"  type="application/srgs+xml"/>
           <catch event="help">
              Please speak the state for which you want the weather.
           </catch>
         </field>
         <field name="city">
           <prompt>What city?</prompt>
           <grammar src="city.grxml" type="application/srgs+xml"/>
           <catch event="help">
              Please speak the city for which you want the weather.
           </catch>
         </field>
         <block>
           <submit next="/servlet/weather" namelist="city state"/>
         </block>
        </form>
      </vxml>
    该对话执行的顺序为:
      C (computer): Welcome to the weather information service. What state?
      H (human): Help.
      C: Please speak the state for which you want the weather.
      H: Georgia.
      C: What city?
      H: Tblisi.
      C: I did not understand what you said. What city?
      H: Macon.
      C: The conditions in Macon Georgia are sunny and clear at 11 AM ...
    FIA的第一次循环选定时,选定了第一个block,因为它的form item变量(隐含的)值为undefined。该block输出了它的提示语,且它的form item变量被置为true。在FIA的第二次反复选定时,略过了第一个block,因为它的form item变量值不为undefined,此时FIA选定了名为“state”的field,因为该field的变量state的值为undefined。该field提示用户输入州名,然后把变量state置为用户输入的答案。关于field级的语法填充form item变量的具体描述见3.1.6节。第三次提示并收集名称为city的field。第四次执行了最后的block,并跳转到另外一个URI。
    这个例子里的每个field都有播放一段提示语引导用户输入,有一个语法指定要监听的内容,有help事件的事件处理。无论何时,只要用户要求帮助,help事件就会被抛出。Help事件处理捕获这些事件并播放一段更详细的提示语。
    下面还有一个机器主导的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 id="get_card_info">
         <block>We now need your credit card type, number, and expiration date.</block>
         <field name="card_type">
           <prompt count="1">What kind of credit card do you have?</prompt>
           <prompt count="2">Type of card?</prompt>
           <!-- This is an inline grammar. -->
           <grammar type="application/srgs+xml" root="r2" version="1.0">
             <rule id="r2" scope="public">
              <one-of>
               <item>visa</item>
               <item>master<item repeat="0-1">card</item></item>
               <item>amex</item>
               <item>american express</item>
              </one-of>
            </rule>
          </grammar>
          <help>Please say Visa, Mastercard, or American Express.</help>
          </field>
          <field name="card_num">
           <grammar type="application/srgs+xml" src="/grammars/digits.grxml"/>
           <prompt count="1">What is your card number?</prompt>
           <prompt count="2">Card number?</prompt>
           <catch event="help">
             <if cond="card_type =='amex' || card_type =='american express'">
               Please say or key in your 15 digit card number.
          <else/>
               Please say or key in your 16 digit card number.
          </if>
         </catch>
          <filled>
           <if cond="(card_type == 'amex' || card_type =='american express') && card_num.length != 15">
               American Express card numbers must have 15 digits.
             <clear namelist="card_num"/>
             <elseif cond="card_type != 'amex'&& card_type !='american express'&& card_num.length != 16"/>
               Mastercard and Visa card numbers have 16 digits.
             <clear namelist="card_num"/>
             <throw event="nomatch"/>
           </if>
          </filled>
        </field>
										
        <field name="expiry_date">
          <grammar type="application/srgs+xml" src="/grammars/digits.grxml"/>
          <prompt count="1">What is your card's expiration date?</prompt>
          <prompt count="2">Expiration date?</prompt>
          <help>
             Say or key in the expiration date, for example one two oh one.
          <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">
           <grammar type="application/srgs+xml" src="/grammars/boolean.grxml"/>
           <prompt>
              I have <value expr="card_type"/> number
             <value expr="card_num"/&> expiring on
             <value expr="expiry_date"/>.
              Is this correct?
           </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 confirm"/>
           </filled>
         </field>
        </form>
      </vxml>
    注意:语法的可选项‘amex’和‘american express’返回的真实值需要在条件表达式中分开处理。3.1.5节描述了语法中的语义元素怎样才能对多种输入返回一个单独的值。
    该对话的流程可能是这样的:
      C: We now need your credit card type, number, and expiration date.
      C: What kind of credit card do you have?
      H: Discover.
      C: I did not understand what you said. (a platform-specific default message.) 
      C: Type of card? (the second prompt is used now.)
      H: Shoot. (fortunately treated as "help" by this platform)
      C: Please say Visa, Master card, or American Express.
      H: Uh, Amex. (this platform ignores "uh") 
      C: What is your card number?
      H: One two three four ... wait ...
      C: I did not understand what you said.
      C: Card number?
      H: (uses DTMF) 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 #
      C: What is your card's expiration date?
      H: one two oh one
      C: I have Amex number 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 expiring on 1 2 0 1. Is this correct?
      H: Yes.
    Field是form的主要组成元素。Field声明了一个变量并指定了相应的提示语、语法、DTMF序列、帮助信息和其他一些事件处理。每个field声明了一个VoiceXML form item变量,它的作用域为该form的dialog。该field被填充后,它的变量可以被提交,也可以赋值给其他的变量。
    每个field有它自己的语音和(或)DTMF语法,既可以明确的使用<grammar>元素指定,也可以用type属性隐含地指定。Type属性用于指定内置的语法,像digits、boolean或number。
    每个field可以有一个或多个提示语。如果有一个提示语,它会被反复地播放给用户,直到用户输入信息。若有多个提示语则根据提示语选择算法来选定提示语(详见4.1.6节)。在每次要播放提示语的时候,count属性可以决定用哪一条提示语。在这个例子,提示语越变越短,这叫做锥形提示(tapered prompting:语音提示渐渐地简短而精炼,或越来越精细)。
    <catch event="help">元素是一个事件处理,它定义了当用户请求帮助时该做什么。帮助信息也可以是分级的。这些信息可以简化,下面两个元素的效果是等同的。
      <catch event="help">
         Please say visa, mastercard, or amex.
      </catch>
										
      <help>
         Please say visa, mastercard, or amex.
      </help>
    <filled>元素定义的是,当用户提供了相应field要识别的输入后该做什么。一个用途就是在语法检查之后再指定一套完整的约束,像上面例子中名为expiry_date的field。
 
五、Mixed Initiative Forms
    上一节我们讨论了执行严格的,由计算机主导的会话,要实现混合主动式的form,即计算机和用户共同主导该会话,必须有一个或多个form级别的语法。这种会话的编写有几种方式,其中一种普遍的方式是使用<initial>元素和<field>元素,<initial>元素用来获得全面的信息,而<field>元素用来获得特定的信息。下面的例子说明了这一点。其他一些更复杂的技巧也可以取得同样的效果,例如使用<initial>元素的cond属性。
    如果某个form拥有几个form级别的语法,那么:
      1、它的input item在任何顺序中都能够被填充;
      2、用户的一个utterance就可以填充一个以上的input item。
    只有input item能够被form级别的语法的匹配结果填充,control item不能。关于form级别的语法填充field变量的描述见3.1.6节。
    当用户在其他的对话内,form级别的语法也可能是激活的。假如某个文档有两个form,一个是汽车租金的form,另一个是酒店预定的form,它们都有在整个文档激活的语法,在和酒店预定的form交互的时候,用户可以输入汽车租金的信息,引导计算机到汽车租金的form里。用户可以根据任何激活的语法讲话,填充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="weather_info">
         <grammar src="cityandstate.grxml" type="application/srgs+xml"/>
         <!-- Caller can't barge in on today's advertisement. -->
         <block>
           <prompt bargein="false">
             Welcome to the weather information service.
             <audio src="http://www.online-ads.example.com/wis.wav"/>
           </prompt>
          </block>
										
         <initial name="start">
           <prompt>
              For what city and state would you like the weather?
           </prompt>
           <help>
             Please say the name of the city and state for which you would like a weather report.
          </help>
          <!-- If user is silent, reprompt once, then try directed prompts. -->
          <noinput count="1"><reprompt/></noinput>
          <noinput count="2"><reprompt/><assign name="start" expr="true"/></noinput>
         </initial>
										
         <field name="state">
           <prompt>What state?</prompt>
             <help>
               Please speak the state for which you want the weather.
            </help>
         </field>
										
         <field name="city">
           <prompt>Please say the city in <value expr="state"/>for which you want the weather.</prompt>
           <help>Please speak the city for which you want the weather.</help>
           <filled>
             <!-- Most of our customers are in LA. -->
             <if cond="city == 'Los Angeles' && state == undefined">
               <assign name="state" expr="'California'"/>
             </if>
           </filled>
         </field>
										
        <field name="go_ahead" modal="true">
          <grammar type="application/srgs+xml" src="/grammars/boolean.grxml"/>
          <prompt>Do you want to hear the weather for <value expr="city"/>, <value expr="state"/>?</prompt>
          <filled>
            <if cond="go_ahead">
              <prompt bargein="false">
                <audio src="http://www.online-ads.example.com/wis2.wav"/>
             </prompt>
             <submit next="/servlet/weather" namelist="city state"/>
            </if>
            <clear namelist="start city state go_ahead"/>
           </filled>
         </field>
        </form>
      </vxml>
    下面是该例子的一个可能的流程,它显示了它的优势,即使该用户是个新手:
      C: Welcome to the weather information service. Buy Joe's Spicy Shrimp Sauce.
      C: For what city and state would you like the weather?
      H: Uh, California.
      C: Please say the city in California for which you want the weather.
      H: San Francisco, please.
      C: Do you want to hear the weather for San Francisco, California?
      H: No
      C: For what city and state would you like the weather?
      H: Los Angeles.
      C: Do you want to hear the weather for Los Angeles, California?
      H: Yes
      C: Don't forget, buy Joe's Spicy Shrimp Sauce tonight!
      C: Mostly sunny today with highs in the 80s. Lows tonight from the low 60s ...
    名称为go_ahead的field有一个modal属性,它的值为true,它的作用是使所有的语法都失效,除了当前form item中定义的那个语法,因此,在该field中只有boolean语法是激活的。
    有经验的用户可以更快的完成流程,但是他还是必须要听广告:
      C: Welcome to the weather information service. Buy Joe's Spicy Shrimp Sauce.
      C: What ...
      H (barging in): LA.
      C: Do you ...
      H (barging in): Yes.
      C: Don't forget, buy Joe's Spicy Shrimp Sauce tonight!
      C: Mostly sunny today with highs in the 80s. Lows tonight from the low 60s ...
    Controlling the order of field collection.
    FIA可以用多种方式定制。其中一种方法是给一个form item变量赋值,这样该form item就不会被选定了;另一种方法是用<clear>把form item变量置为undefined,强制FIA再次访问该form item。
    还有一种是用<goto>元素的nextitem属性明确地指定下一个要访问的form item,该方法强加了一个到目标form item 的立即跳转。目标form item的变量、条件和计数器都不会被重置。即使该form item已经被访问过,他的提示语还是会播放的。如果<goto nextitem>跳转出现在<filled>中,该<filled>剩下的操作和任何挂起的<filled>操作都会被跳过。
    下面这个例子中<goto nextitem>出现在exit事件的事件处理中:
      <?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="survey_2000_03_30">
           <catch event="exit">
             <reprompt/>
             <goto nextitem="confirm_exit"/>
           </catch>
           <block>
             <prompt>
                Hello, you have been called at random to answer questions critical to U.S. foreign policy.
             </prompt>
           </block>
										
           <field name="q1">
             <grammar type="application/srgs+xml" src="/grammars/boolean.grxml"/>
             <prompt>Do you agree with the IMF position on privatizing
                 certain functions of Burkina Faso's agriculture ministry?</prompt>
          </field>
										
          <field name="q2">
           <grammar type="application/srgs+xml" src="/grammars/boolean.grxml"/>
             <prompt>If this privatization occurs, will its effects be
                  beneficial mainly to Ouagadougou and Bobo-Dioulasso?</prompt>
         </field>
										
          <field name="q3">
           <grammar type="application/srgs+xml" src="/grammars/boolean.grxml"/>
             <prompt>Do you agree that sorghum and millet output might
                   thereby increase by as much as four percent per annum?</prompt>
         </field>
										
         <block>
           <submit next="register" namelist="q1 q2 q3"/>
         </block>
										
        <field name="confirm_exit">
           <grammar type="application/srgs+xml" src="/grammars/boolean.grxml"/>
           <prompt>You have elected to exit.  Are you sure you want to do this, and perhaps 
             adversely affect U.S. foreign policy vis-a-vis sub-Saharan Africa for decades 
             to come?</prompt>
										
         <filled>
           <if cond="confirm_exit">
             Okay, but the U.S. State Department is displeased.
             <exit/>
            <else/>
             Good, let's pick up where we left off.
             <clear namelist="confirm_exit"/>
            </if>
          </filled>
          <catch event="noinput nomatch">
            <throw event="exit"/>
          </catch>
         </field>
        </form>
      </vxml>
    无论用户在哪个要收集的问题中说“exit”,平台都会抛出exit事件,并由<catch>元素的事件处理捕获。该事件处理把FIA引导到下一个要访问的field,“confirm_exit”。confirm_exit域在正常的调查完成过程中将不再被访问,因为其前面的<block>元素将控制转向“register”脚本。
 
六、Form Interpretation Algorithm
    我们已经从概念上讨论了FIA,在这一节,我们将更详细地讨论它(更详细的描述见附录C)。
 
    <一>、Initialization Phase
    FIA只要进入一个form就会初始化它。内部的提示语计数器变量(在form的dialog作用域内)被置为1。每个变量(form级别的<var>元素和form item变量)根据在文档中的顺序被一一初始化为undefined和相应的expr属性的值。
 
    <二>、Main Loop
    FIA的主循环有三个阶段:
    选定(select)阶段:选定下一个没有被填充的form item供访问。
    收集(collect)阶段:访问被选定的form item,播放它的提示语让用户输入,激活相应的语法,等待收集用户的输入(例如语音或DTMF按键输入)或者事件(例如请求帮助或noinput timeout)。
    处理(process)阶段:处理用户输入,填充form item并执行<filled>元素的操作,例如确认输入;处理事件,执行该事件相应的事件处理。
    注意:FIA可以被给定一个输入(一组语法槽值(grammar slot/slot value pairs)),该输入是用户在另外一个FIA时被收集到的。在这种情况下,主循环的第一次循环跳过了选定和收集阶段,直接跳到处理阶段,使用给定的输入处理。另一个要注意的是,如果在选定或收集阶段有错误发生,产生一个事件,该事件被抛出,FIA也直接跳到处理阶段。
 
      1、Select phase
      选定阶段的目的是选定下一个要访问的form item,当出现以下情况时,选定阶段结束:
      如果上一次主循环的处理阶段指定了一个<goto nextitem>,则该指定的form item被选定。
      另外,如果第一个form item的警戒条件为false,则该form item被选定。在检查警戒条件时,如果发生错误,事件被抛出,FIA跳过收集阶段,进入处理阶段,处理该事件。
      如果没有任何form item的警戒条件为false,且FIA最后一次循环完成时没有碰到明确的控制跳转,FIA会执行一个隐含的<exit>操作(类似的,如果执行是在form 之外,例如当在form之外产生一个错误时,没有任何明确的控制跳转,解释器将执行一个隐含的<exit>操作)。
 
      2、Collect phase
      收集阶段的目的是收集用户输入或事件。当一个form item被选定时,FIA要执行的操作取决于该form item的类型:
      如果访问的是一个field item,FIA根据该field item的提示语计数器和提示语条件选定提示语,进行排队,然后激活并监听该field级别的语法和任何其他更高级别的激活的语法,等待语法识别和某个事件。
      如果访问的是<transfer>,FIA根据提示语计数器和提示语条件对提示语进行排队,激活该item的语法,在该transfer执行前播放它的提示语队列。
      如果访问的是<subdialog>或<object>,FIA根据提示语计数器和提示语条件对提示语进行排队,FIA没有激活语法,相反,执行环境给subdialog或object指定了收集输入的行为。在执行subdialog或object之前不播放提示语队列,而应该在后来的输入收集的时候播放。
      如果访问的是<initial>,FIA根据该<initial>的提示语计数器和提示语条件选定提示语,进行排队,然后监听form级别的语法和其他更高级别的激活的语法,等待语法识别和某个事件。
      如果访问的是<block>,FIA把它的form item 变量置为true,对它的内容求值,跳过处理阶段,没有收集任何输入,FIA主循环的下一次循环进入该<block>。
 
      3、Process phase
      处理阶段的目的是处理上一个阶段收集到的输入或事件。
        (1)、如果出现一个事件(如noinput或挂机),FIA确定该应用的catch元素并执行它,该应用catch元素在当前form item 的范围内选定,在该会话封装的范围内进行,这样可能会导致该FIA终止(例如,如果它跳转到一个对话或文档,或执行了<exit>),或者可能导致FIA进入主循环的下一个循环(如,执行帮助的默认事件处理)。
        (2)、如果某个输入匹配了<link>语法,则FIA执行该link的跳转,或者抛出它的事件,如果<link>抛出一个事件,事件在当前的form item(如<initial>、 <field>、<transfer>等等)的环境下处理。
        (3)、如果输入匹配了一个不同于当前form的另一个form的语法,该FIA终止,另一个form被初始化,该form的FIA带着这个输入直接进入它的处理阶段。
      如果某个输入匹配了该form的语法,则:
        (1)、该语法的语义结果被映射到一个或多个form item变量,详细描述见3.1.6节;
        (2)、FIA标识这些赋值所触发的<filled>操作,详细描述见24节;
        (3)、FIA根据它们在文档中的顺序执行每个<filled>操作。如果遇到<submit>、<disconnect>、<exit>、<return>、<goto>或者<throw>元素,就不会再执行剩下的<filled>元素了,FIA要么终止,要么继续主循环的下一个循环。<reprompt>不会终止FIA(终止意味着一个操作),只是相当于给相应的prompt做个标记,让FIA在下一次循环再次播放prompt。如果在执行某个<filled>时抛出一个事件,FIA将在该<filled>的作用域内开始选定事件处理,该作用域可以是一个 form item或者该form自己,然后在该dialog作用域外处理。
      在完成处理阶段后,解释器继续返回到选定阶段。
    关于FIA更详细的描述见附录C。

第二节 Menus  
 
    menu在语法上是一个form的另一种形式,该form包含了单个的匿名的field。menu提示选择一个选项,并根据该选项跳转到相应的dialog。就像一个正规的form一样, menu也有它自己的语法作用域,例如当用户在执行另一个dialog时,它的语法也可以是激活的。下面的例子中,menu给用户提供了3个选项:
      <?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">
        <menu>
          <prompt>
             Welcome home. Say one of: <enumerate/>
          </prompt>
          <choice next="http://www.sports.example.com/vxml/start.vxml">
             Sports
          </choice>
          <choice next="http://www.weather.example.com/intro.vxml">
             Weather
          </choice>
          <choice next="http://www.stargazer.example.com/voice/astronews.vxml">
              Stargazer astrophysics news
          </choice>
         <noinput>Please say one of <enumerate/></noinput>
        </menu>
      </vxml>
    下面是该dialog可能的流程:
      C: Welcome home. Say one of: sports; weather; Stargazer astrophysics news.
      H: Astrology.
      C: I did not understand what you said. (a platform-specific default message.) 
      C: Welcome home. Say one of: sports; weather; Stargazer astrophysics news.
      H: sports.
      C: (proceeds to http://www.sports.example.com/vxml/start.vxml) 
 
一、MENU
    <menu>元素可以标识一个菜单,并确定它的语法的作用域。Menu的属性如下:
id Menu的标识符,它允许dialog通过<goto>或<submit>跳转到该menu。
scope Menu的语法作用域。如果它的值为“dialog”,只有当用户跳转到该menu,它的语法才是激活的。如果它的值为“document”,它的语法在整个文档内(或者,如果该menu在应用根文档里,在该应用中,所有加载的文档内)都是激活的。
dtmf 当它的值为“true”,前九个choice如果没有明确的指定dtmf属性,则它们会得到隐含的dtmf属性,如“1”、“2”等。剩下的那些没有明确指定dtmf属性的choice不会得到DTMF值(因此它们不能通过DTMF按键来匹配)。此时,如果该menu有choice指定了它自己的DTMF序列,该序列包含除了“*”、“#”或“0”以外的字符,平台要抛出error.badfetch 事件。该属性默认值为“false”。
accept 当它的值为“exact”(该值为默认值),则该menu中的choice元素的文本定义的是要识别的精确的短语。如果它的值为“approximate”,则该menu中的choice元素的文本定义的是要识别的近似的短语(如2.2.5节中描述的)。<choice>的accept属性的优先权高于menu的该属性。
表7:<menu>元素的属性
 
二、CHOICE
    <choice>元素有下面几个作用:
      1、它可以指定一个语音语法,用<grammar>元素定义或由程序自动产生,详细描述见2.2.5节;
      2、它可以指定一个DTMF语法,详见2.2.3节;
      3、它的内容可以作为<enumerate>的提示语,详见2.2.4节;
      4、当某个选项被选择的话,它要么指定了要抛出的事件,要么指定了要跳转的URI。
    <choice>的属性有:
dtmf 该<choice>元素的DTMF序列。它的作用等同于一个简单的DTMF语法,或者应用于该序列识别的DTMF property(6.3.3节)。它和DTMF不同的是,它的空格是不起作用的:dtmf=“123#”和 dtmf=“1 2 3 #”是等同的。
accept 该<choice>元素的“accept”属性的优先权高于所在的<menu>元素的“accept”属性。当该属性的值为“exact”(默认),<choice>元素的文本定义了要识别的精确的短语;当该属性值为“approximate”,<choice>元素的文本定义的是要识别的近似的短语(详见2.2.5节)。
next 要跳转的下一个对话或文档。
expr 一个表达式,它的值为要跳转的URI,而不指定“next”属性。
event 指定一个要抛出的事件,而不指定“next”属性。
eventexpr 一个ECMAScript表达式,它的值为要抛出的事件名。
message 一个信息串,它提供了关于要抛出的事件的上下文。在<catch>元素的作用域内用变量“_message”可以得到该信息串,详见5.2.2。
messageexpr 一个 ECMAScript表达式 ,它的值为一个信息串。
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的值。
表8:<choice>元素的属性
    必须正确地指定属性“next”、“expr”、“event”和“eventexpr”中的一个,否则会抛出error.badfetch事件。也可以正确地指定属性“message”或“messageexpr”中的一个,否则会抛出error.badfetch事件。
    如果在<choice>中指定了一个<grammar>元素,则该外部语法用于替换自动产生的语法。这样开发者就可以准确地控制<choice>元素的语法,例如:
      <?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">
        <menu>
          <choice next="http://www.sports.example.com/vxml/start.vxml">
             <grammar src="sports.grxml" type="application/srgs+xml"/>
             Sports
          </choice>
          <choice next="http://www.weather.example.com/intro.vxml">
             <grammar src="weather.grxml" type="application/srgs+xml"/>
             Weather
          </choice>
          <choice next="http://www.stargazer.example.com/voice/astronews.vxml">
             <grammar src="astronews.grxml" type="application/srgs+xml"/>
              Stargazer astrophysics
          </choice>
        </menu>
      </vxml>
 
三、DTMF in Menus
    menu可以只有语音语法,也可以只有DTMF语法,也可以在<menu>中包含一个<property>元素同时指定DTMF和语音语法。下面的例子中的menu只有DTMF语法,并且使用<choice>元素的dtmf属性给每个<choice>元素显式的指定了DTMF序列:
      <?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">
        <menu>
          <property name="inputmodes" value="dtmf"/>
          <prompt>
             For sports press 1, For weather press 2, For Stargazer astrophysics press 3.
          </prompt>
          <choice dtmf="1" next="http://www.sports.example.com/vxml/start.vxml"/>
          <choice dtmf="2" next="http://www.weather.example.com/intro.vxml"/>
          <choice dtmf="3" next="http://www.stargazer.example.com/astronews.vxml"/>
        </menu>
      </vxml>
    另外,也可以把<menu>元素的dtmf属性置为true,自动的为前九个没有指定DTMF序列的<choice>元素指定一个DTMF序列,第一个为“1”,等等:
      <?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">
        <menu dtmf="true">
          <property name="inputmodes" value="dtmf"/>
          <prompt>
             For sports press 1, For weather press 2, For Stargazer astrophysics press 3.
          </prompt>
          <choice next="http://www.sports.example.com/vxml/start.vxml"/>
          <choice next="http://www.weather.example.com/intro.vxml"/>
          <choice dtmf="0" next="#operator"/>
          <choice next="http://www.stargazer.example.com/voice/astronews.vxml"/>
        </menu>
      </vxml>
 
四、ENUMERATE
    <enumerate>元素用于为用户自动产生<choice>元素的描述,它指定了一个模板,该模板根据<choice>元素在<menu>元素中的顺序,依次应用于每个<choice>。如果<enumerate>中没有内容,则使用默认的模板,列出所有的<choice>。该默认的模板取决于解释器环境。如果<enumerate>中有内容,这些内容就是模板的样式,它可以引用两个专有变量,“_prompt”和“_dtmf”,前者表示<choice>元素的提示语,后者表示<choice>元素的DTMF序列。如下面的例子:
      <?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">
        <menu dtmf="true">
         <prompt>
           Welcome home.
           <enumerate>
             For <value expr="_prompt"/>, press <value expr="_dtmf"/>.
           </enumerate>
         </prompt>
         <choice next="http://www.sports.example.com/vxml/start.vxml">
            sports </choice>
         <choice next="http://www.weather.example.com/intro.vxml">
            weather </choice>
         <choice next="http://www.stargazer.example.com/voice/astronews.vxml">
            Stargazer astrophysics news </choice>
        </menu>
      </vxml>
    该menu的提示语为:
      C: Welcome home. For sports, press 1. For weather, press 2. For Stargazer astrophysics news, press 3.
    <enumerate>元素可用于<menu>元素中的<promppt>和<catch>元素,也可以用于包含有<option>元素的<field>元素。如果<enumerate>用于其他的地方,平台会抛出error.semantic事件(例如<enumerate>元素中包含有<enumerate>元素)。
 
五、Grammar Generations
    每个选项的文本(choice phrase)都指定了一组要监听的词或短语。一个选项的文本由直接或间接包含在<menu>元素中的<choice>元素中的元素的PCDATA组成,或由<field>元素中的<option>元素的PCDATA组成。
    如果accept的属性值为“exact”,则用户必须匹配选项文本中的整个短语,且顺序也要相同。
    如果accept的属性值为“approximate”,则用户可以匹配选项文本中的短语的子短语。例如,对于响应选项文本“Stargazer astrophysics news”,用户可以说“Stargazer”, “astrophysics”, “Stargazer news”, “astrophysics news”等。产生的语法是依赖语语言和平台的。
    如下面的例子,在不同的选项中分别使用“exact”和“approximate”。
      <?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">
        <menu accept="approximate">
          <choice next="http://www.stargazer.example.com/voice/astronews.vxml">
             Stargazer Astrophysics News </choice>
          <choice accept="exact" next="http://www.physicsweekly.com/voice/example.vxml">
             Physics Weekly </choice>
          <choice accept="exact" next="http://www.particlephysics.com/voice/example.vxml">
             Particle Physics Update </choice>
          <choice next="http://www.astronomytoday.com/voice/example.vxml">
             Astronomy Today </choice>
        </menu>
      </vxml>
    由于第一个选项的accept属性值为“approximate”,因此要匹配这个选项,用户可以只说出子短语;例如“Stargazer”或“Astrophysics News”。然而,由于第二个和第三个选项的accept属性值为“exact”,因此只有说出整个短语“Physics Weekly”和“Particle Physics Update”才能匹配语法。
    在下面的例子中,在<choice>元素中使用了PCDATA:
      <choice accept="exact" next="http://www.stargazer.example.com/voice/astronews.vxml">
        <audio src="http://www.stargazer.example.com/space.wav">
           Stargazer <emphasis>astrophysics</emphasis> news
        </audio>
      </choice>
    该<choice>元素的选项文本由音频文件播放,如果该音频文件不能被播放,则会以语音合成的方式播放“Stargazer Astrophysics News”。该<choice>元素的语法的精确匹配短语“Stargazer astrophysics news”来自<choice>元素的PCDATA。
 
六、Interpretation Model
    <menu>和只包含一个简单的<field>的<form>的工作机制类似。Menu的事件处理相应的对应于<field>的事件处理。<menu>的语法相应的对应于<form>的语法。和在<form>中一样,<menu>中的语法匹配也会更新数组application.lastresult$。这些变量在5.1.5节中由详细描述。
    一旦进入<menu>,它的语法就被自动生成并激活,然后播放提示语。当用户的输入匹配了一个<choice>控制该<choice>的next, expr, event或eventexpr属性值跳转。这四个属性中,同时只可以指定一个。如果指定了一个event属性,而该事件的事件处理没有让解释器退出或把控制跳转到其他dialog,则FIA会将该<menu>的anonymous field清零,再次执行该<menu>。


第三节 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>执行后,是否依然监控主叫方和被叫方。
trueBridge transfer:VoiceXML解释器一直处于等待状态,直到Transfer从转接通话状态下退出。如果因为挂机或网络的原因而线路中断,会抛出一个Connection.disconnect.hangup事件。如果通话因为其它原因而中断,中断原因会写在元素的属性里。
falseBlind 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事件。
 


posted on 2006-09-16 21:42 铁观音 阅读(2445) 评论(0)  编辑 收藏 引用 所属分类: VoiceXML2.0规范