铁观音

C++编程宝典

   ::  ::  ::  ::  :: 管理 ::
  1 随笔 :: 19 文章 :: 0 评论 :: 0 Trackbacks
第五章  Control flow and scripting
 
第一节 Variables and Expressions  
 
    VoiceXML变量和ECMAScript变量是完全等同的:它们在同一个变量空间。VoiceXML变量可在<scrpit>元素中使用,就像<scrpit>元素中定义的变量可在VoiceXML中使用一样。使用<var>元素声明一个变量和在<scrpit>元素中用var语句声明的变量效果是等同的。<scrpit>元素可出现在任何<var>元素能够出现的地方。Form item也可以声明VoiceXML变量。
    VoiceXML中变量的命名规则与在ECMAScript中一样,但是以下划线“_”开头或以美元符号"$"结尾命名的变量被保留用于内部使用。VoiceXML变量,包括form item变量,一定不能包含ECMAScript的保留字。在有关的正确性上必须遵循ECMAScript的规则。例如,变量名必须是唯一的,且声明变量一定不能够包括点号――“var x.y”在ECMAScript中是非法的声明。如果变量名和命名规则或ECMAScript规则冲突,抛出‘error.semantic’事件。
 
一、Declaring Variables
    变量声明使用<var>元素:
       <var name="home_phone"/>
       <var name="pi" expr="3.14159"/>
       <var name="city" expr="'Sacramento'"/> 
    form item也可以声明变量:
       <field name="num_tickets">
         <grammar type="application/srgs+xml" src="/grammars/number.grxml"/>
         <prompt>How many tickets do you wish to purchase?</prompt> 
       </field>
    如果已声明的变量没有显式的给定初始值,则该变量的默认值为ECMAScript的undefined。不管在VoiceXML中还是在ECMAScript中,变量在使用之前都要声明。使用没有声明的变量会导致一个ECMAScript错误,并抛出error.semantic事件。<scrpit>元素中使用var语句声明的变量可在VoiceXML中使用,就像VoiceXML变量可在<scrpit>元素中使用一样。
    在form中,变量由<var>元素声明,那些由form item声明的变量在FIA进入该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="test">
           <var name="one" expr="1"/>
           <field name="two" expr="one+1">
              <grammar type="application/srgs+xml" src="/grammars/number.grxml"/>
           </field>
           <var name="three" expr="two+1"/>
           <field name="go_on" type="boolean">
              <prompt>Say yes or no to continue</prompt>
           </field>
        </form>
      </vxml>
    当用户访问该<form>元素时,该form的初始化首先声明变量one,并把它的值置为1。然后声明field变量two,并把它的值置为2。接着声明变量three,并把它的值置为3。最后FIA进入解释的主循环,从<field>元素go_on开始。
 
二、Variable Scopes
    VoiceXML使用ECMAScript作用域链,允许在应用的不同层次中声明变量。例如,在文档的作用域中声明的变量在该文档的任何地方都可以引用。而在<catch>元素中声明的本地变量只能在该<catch>元素中被引用。为了保护各个作用域变量的语义,所有的ECMAScript变量都要声明。使用没有声明的变量会导致一个ECMAScript错误,并抛出error.semantic事件。
    变量有如下几个作用域:
session 这是一些只读的变量,在整个用户会话期间都是可用的。它们由解释器环境声明并设置。在VoiceXML文档中不能再声明新的session变量。见5.1.4节。
application 这是一些由<var>元素和<script>元素声明的变量,且<var>元素和<script>元素都是应用根文档的<vxml>元素的子元素。这些变量在加载应用根文档时被初始化。在应用根文档被加期间,这些变量都是存在的,且在应用根文档和应用叶文档中都可以访问它们。注意,当在应用根文档中执行时,document.x和application.x是等价的。
document 这是一些由<var>元素和<script>元素声明的变量,且该<var>元素和<script>元素都是该文档的<vxml>元素的子元素。这些变量在加载文档时被初始化。在文档被加期间,这些变量都是存在的,且只能在该文档中访问它们。除非该文档是应用根文档,在这种情况下,在应用根文档和应用叶文档中都可以访问它们。
dialog 每个dialog(<form>元素或<menu>元素)都有一个dialog作用域,当用户访问该dialog时,该作用域才存在。Dialog变量是由<var>元素和<script>元素声明的变量,且该<var>元素和<script>元素都是<form>元素或<menu>元素的子元素;Dialog变量也可以是由各种form item声明的变量。<form>元素的<var>子元素和<script>子元素在该<form>元素被首次访问时初始化。<var>元素里面的可执行内容在执行可执行内容时被初始化。Form item变量在该form item被选定时初始化。
(anonymous) 每个<block>元素,<filled>元素,和<catch>元素定义了一个新的anonymous作用域。在这些元素中声明的变量的作用域即为anonymous 。它们只能在相应的<block>元素,<filled>元素,或<catch>元素中被引用。
表39:变量的作用域
    下面的图表就是作用域层次:
图11: 作用域层次
    在上面的图中,弯曲的箭头表示每个作用域都包含了一个和该作用域名称一样的预定义的变量,该变量引用的是作用域本身。例如,在anonymous, dialog, 和document作用域内可以使用document.x引用该文档中作用域为document的变量x。另外一个例子,例如,<field>元素的变量作用域为anonymous,它只能在该<field>元素中使用,它上一级的变量作用域为该<field>元素所在的<form>元素内,即dialog。
    我们不推荐使用“session”,“application”,“document”和 “dialog”作为变量名或form item名。虽然它们不是保留字,但是由于VoiveXML使用的是ECMAScript的作用域规则,使用这些词作为变量名的话,会覆盖同名的预定义变量。
 
三、Referencing Variables
    变量可以在属性cond和expr中使用:
       <if cond="city == 'LA'">
         <assign name="city" expr="'Los Angeles'"/>
       <elseif cond="city == 'Philly'"/>
         <assign name="city" expr="'Philadelphia'"/>
       <elseif cond="city =='Constantinople'"/>
         <assign name="city" expr="'Istanbul'"/>
       </if>
										
       <assign name="var1" expr="var1 + 1"/>
										
       <if cond="i > 1">
         <assign name="i" expr="i-1"/>
       </if>
    在属性cond和expr中使用的表达式的语言正是ECMAScript。注意,属性cond中的操作符“<”,“<=”和“&&”必须使用XML的转义字符(如“<”,等等)。
    根据上述的变量作用域链,变量引用将匹配离其最近的包含它的作用域。你可以为变量引用加上前缀,前缀名即为作用域名,这样变量引用将变得很明确。例如,保存一个field item变量为document变量,以被以后使用:
       <assign name="document.ssn" expr="dialog.ssn"/>
    如果应用根文档有一个变量x,则它可在非根文档中使用application.x引用该变量,而在该应用根文档中则可使用application.x或document.x引用该变量。如果该文档有一个变量x,且没有指定属性application,则在该文档中可使用application.x或document.x引用该变量。
 
四、Standard Session Variables
    session.connection.local.uri
    该变量的值是一个执行本地解释器环境设备的URI。
    session.connection.remote.uri
    该变量的值是一个指向远程主叫设备的URI。
    session.connection.protocol.name
    该变量的值为连接协议的名称,也可以通过该名称的子对象名获得该协议中特定的信息。例如,如果链接协议名为“q931”,则session.connection.protocol.q931.uui可能指定了该连接的user-to-user information的属性值。
    session.connection.protocol.version
    该变量的值为连接协议的版本号。
    session.connection.redirect
    该变量是一个数组,内含连接重定向的路径。第一个元素是原来的被叫号码,最后一个元素是最后重定向的号码。该数组中的每个元素都包含了URI,pi(presentation information), si(screening information)和reason属性。Reason的属性值可以是“unknown”,“user busy”,“no reply”,“deflection during alerting”,“deflection immediate response”,“mobile subscriber not reachable”。
    session.connection.aai
    该变量的值为连接建立时传递的application-to-application information信息。
    session.connection.originator
    该变量的值为该连接的local或remote属性值,例如,如果是remote部分初始化该连接,则下面的ECMAScript将返回true:var caller_initiate = connection.originator == connection.remote。
 
五、Standard Application Variables
    application.lastresult$
    该变量保存了该应用中最后一次识别的信息。它是一个数组,每个元素通过下面的变量表示一个可能的结果:
      application.lastresult$[i].confidence
    该变量表示,这次解释中整个utterance的confidence级别。取值的范围为0.0-1.0。0.0表示最低的condence,1.0表示最高的confidence。对confidence的值的解释是依赖于平台的。
    application.lastresult$[i].utterance
    该变量表示,这次解释被识别的词的原始字符串。确切的标记和拼写是依赖于平台的(如“five hundred thirty”或者“5 hundred 30”或者“530”)。在DTMF的情况下,该变量包含的是匹配的数字的字符串。
    application.lastresult$[i].inputmode
    该变量表示,在这次解释中用户使用的输入方式,值为dtmf或voice。
    application.lastresult$[i].interpretation
    该ECMAScript变量包含了这次识别的语义解释,如3.1.5节中描述的。
    语义的解释根据confidence的分数由高到低排序,若confidence的分数一样,则根据产生该解释的语法中的优先权(见3.1.4节)进一步排序。在变量application.lastresult$中,不同元素的utterance和interpretation一般都不一样,或者两者都不一样。
    变量application.lastresult$中元素的数量总是大于或等于1,且小于或等于系统的“maxnbest” property值。如果系统没有产生任何结果,则“application.lastresult$”的值应该为ECMAScript的undefined。
    另外,直接引用application.lastresult$的属性confidence, utterance, inputmode, 和 interpretation等价于引用该数组中第一个元素的属性(如application.lastresult$.confidence = application.lastresult$[0].confidence)。
    上述的影子变量在每次识别后马上被赋值,在这种情况下,<nomatch>事件也是作为识别的结果的,且它会导致application.lastresult$被赋值,即使<nomatch>事件没有影响到原有的field变量的值。相反,<noinput>事件不会改变application.lastresult$的值。一旦application.lastresult$被赋值后,它的值会一直保持不变(除非被该应用更改了),直到浏览器进入下一次的等待状态才被置为undefined。类似于加载应用根文档时,变量被置为undefined一样。变量application.lastresult$和它的属性都是可写的,可被应用更改。
    下面的例子表明了,怎样在field级别的<catch>元素中使用application.lastresult$变量访问<link>元素中的语法的识别结果。
      <?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">
        <link event="menulinkevent">
           <grammar src="/grammars/linkgrammar.grxml" type="application/srgs+xml"/>
        </link>
										
        <form>
           <field>
             <prompt> Say something </prompt>
             <catch event="menulinkevent">
               <if cond="application.lastresult$.confidence < 0.7">
                 <goto nextitem="confirmlinkdialog"/>
               <else/>
                 <goto next="./main_menu.aspl"/>
               </if>
             </catch>
           </field>
        </form>
      </vxml>
    下面的例子表明了,在<script>元素中怎样遍历application.lastresult$数组:
      <?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="color">
           <prompt> Say a color </prompt>
           <grammar type="application/srgs+xml" src="color.grxml" />
           <filled>
           <var name="confident_count" expr="0"/>
             <script>
             <![CDATA[>
            // number of results
               var len = application.lastresult$.length;
										
               // iterate through array
               for (var i = 0; i < len; i++) {
                // check if DTMF
                 if (application.lastresult$[i].confidence > .7) {
                   confident_count++;
                 }
               }
              ]]>
             </script>
             <if cond="confident_count > 1">
               <goto next="#verify"/>
             </if>
           </filled>
          </field>
        </form>
      </vxml>
 
第二节 Event Handling  
 
    当用户没有响应,或没有清楚的响应或请求帮助等,平台会抛出事件。如果发现VoiceXML文档中有语义错误时,或执行了<throw>元素时,解释器会抛出事件。事件由字符串表示。
    每个可能发生事件的元素都可以有以下一组<catch>元素。
      ·<catch>
      ·<error>
      ·<help>
      ·<noinput>
      ·<nomatch>
    如果需要的话,元素会从他的上层元素继承<catch>元素(“as if by copy”)。例如,<field>元素中没有包含一个<nomatch>元素,但是包含它的<form>元素有,则使用该<form>元素中的<nomatch>元素。这样,可以在任何层次指定公共的事件处理,该事件处理在该层次所包含的所有元素中都可以使用。
    “as if by copy”这句话表明,<catch>元素的继承是指,当执行该<catch>元素时,变量解析和抛出的事件的处理是在事件被抛出的相关作用域内进行的,而不是在包含<catch>元素的作用域内。例如,考虑一下这种情况,在document的作用域内定义一个<catch>元素,该<catch>元素处理一个该文档的<field>元素中产生的事件。在这种情况下,<catch>元素中的变量引用是相对于该<field>的作用域解析的。如果<catch>元素捕获该<field>元素中的一个事件,也是相对于该<field>的作用域进行处理的。同样的,<catch>元素中相对URI的引用也是相对于激活的文档解析的,而不是相对于包含该<catch>元素的文档。最后,对property的解析也是相对于产生事件的那个元素。例如,document级的<catch>元素中的<prompt>元素如果没有指定timeout属性的话,将使用离事件产生的地方最近的一层的timeout属性值。
 
一、Throw
    <throw>元素用于抛出一个事件。可以抛出预定义的事件:
       <throw event="nomatch"/>
       <throw event="connection.disconnect.hangup"/>
    也可以抛出应用定义的事件。
       <throw event="com.att.portal.machine"/
    <throw>元素的属性有:
event 要抛出的事件。
eventexpr ECMAScript表达式,它的结果值为要抛出的事件。
message 有关被抛出的事件的信息。对于抛出的预定义的事件,该message的值是依赖于平台的。在<catch>元素中,可通过“_message”变量取得该信息,见5.2.2节。
messageexpr ECMAScript表达式。其结果值为有关被抛出的事件的信息。
表40:<throw>元素的属性
    必须正确的指定属性“event”,“eventexpr”或 “namelist”中的一个,否则会抛出一个error.badfetch事件。可以正确的指定属性“message”或“messageexpr”中的一个,否则会抛出一个error.badfetch事件。
    除非显式的规定,否则VoiceXML不会指定事件何时会被抛出。
 
二、Catch
    <catch>元素将文档、对话、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="launch_missiles">
           <field name="user_id" type="digits">
              <prompt>What is your username</prompt>
           </field>
           <field name="password">
              <prompt>What is the code word?</prompt>
              <grammar version="1.0" root="root">
                <rule id="root" scope="public">rutabaga</rule>
              </grammar>
              <help>It is the name of an obscure vegetable.</help>
              <catch event="nomatch noinput" count="3">
                <prompt>Security violation!/prompt>
                <submit next="http://www.example.com/apprehend_felon.vxml" 
                        namelist="user_id"/>
              </catch>
           </field>
        </form>
      </vxml>
    <catch>元素的匿名变量包括一个专有的变量“_event”,它保存了被捕获的事件名。例如,下面的<catch>元素可以处理两种事件:
      <catch event="event.foo event.bar">
        <if cond="_event=='event.foo'">
           <!-- Play this for event.foo events -->
           <audio src="foo.wav"/>
         <else/>
           <!-- Play this for event.bar events -->
           <audio src="bar.wav"/>
         </if>
         <!-- Continue with common handling for either event -->
      </catch>
    上面的“_event”变量的作用是根据被捕获的事件检查该播放哪个音频。如果event.foo事件被捕获,就播放foo.wav;如果event.bar事件被捕获,就播放bar.wav。<catch>元素包含的剩下的可执行内容对两类事件的处理都是一样的。
    <catch>元素的匿名变量也包括专有变量“_mesage”,它保存了来自相应的<throw>元素的message字符串的值,或者平台为预定义事件产生的依赖于平台的值。如果被抛出的事件没有指定message,则该“_message”的值为ECMAScript 的undefined。
    如果<catch>元素包含了一个<throw>,且<catch>要捕获的事件和<throw>元素抛出的事件一样的话,会形成一个无限循环:
      <catch event="help">
        <throw event="help"/>
      </catch>
    平台要能够检测到这种情况,并抛出一个语义错误。
    <catch>元素的属性:
event 要捕捉的一个或多个事件。可以指定多个事件的列表,事件之间用空格隔开。这样表示该<catch>元素将捕捉列表中所有的事件。在这种情况下,每个事件有一个单独的计数器。如果没有指定该属性,则表示所有的事件都会被捕捉。
count 表示事件发生的次数(默认为1)。该属性可以让你对同一事件发生的不同次数进行不同的处理。
每个<form>,<menu>和form item对发生的每个事件都有一个事件计数器。Item级别的事件计数器用于在访问该form item和执行该form item的<filled>元素时抛出的事件。Form级别和menu级别的事件计数器用于在初始化该dialog和执行form级别的<filled>元素时抛出的事件。
当<menu>元素和<form>元素被重新进入时,该form级别或menu级别的事件计数器被重置。<clear>元素不会重置该form级别或menu级别的事件计数器。
每当<form>元素被重新进入时,该<form>元素所包含的item的item级别的事件计数器被重置。当item被<clear>元素重置时,该item的事件计数器也被重置。如果没有离开该form,且该item被重新进入时,该item的事件计数器不会被重置。
事件计数器增加时,它的全名和匹配该事件的各个前缀都会增加。例如,事件“event.foo.1”的发生使“event.foo.1” 、“event.foo”和“event”的事件计数器都增加1。
cond ECMAScript表达式。只有当其结果值为 boolean true,才执行该元素。缺省时为 true。
表41:<catch>元素的属性
 
三、快捷标记
    <error>、<help>、<noinput>和<nomatch>元素都是<catch>元素特定形式的快捷标记。
    <error>元素是<catch event="error">的快捷标记,他用于捕获所有类型的error事件:
       <error>
         An error has occurred -- please call again later.
         <exit/>
       </error>
    <help>元素是<catch event="help">的快捷标记。
       <help>No help is available.</help>
    <noinput>元素是<catch event="noinput">的快捷标记
       <noinput>I didn't hear anything, please try again.</noinput>
    < nomatch>元素是<catch event=" nomatch ">的快捷标记
       <nomatch>I heard something, but it wasn't a known city.</nomatch>
    这些元素都有如下属性:
count 要捕获的事件发生的次数(和<catch>元素中的count属性一样)。
cond 一个表达式,用于测试该元素是否捕捉该事件(和<catch>元素中的cond属性一样),默认为true。
表42:<catch>元素的快捷标记的属性
 
四、Catch Element Selection
    一个元素如果需要的话,将从它的每个上层元素继承(“as if by copy”)<catch>元素。例如,如果<field>元素从文档继承<catch>元素
      <?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">
        <catch event="event.foo">
           <audio src="beep.wav"/>
        </catch>
										
       <form>
           <field name="color">
              <prompt>Please say a primary color</prompt>
           <grammar type="application/srgs">red | yellow | blue</grammar>
              <nomatch>
                <throw event="event.foo"/>
              </nomatch>
           </field>
        </form>
      </vxml>
    则该<catch>元素被隐式的拷贝到该<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>
           <field>
              <prompt>Please say a primary color</prompt>
           <grammar type="application/srgs">red | yellow | blue</grammar>
              <nomatch>
                <throw event="event.foo"/>
              </nomatch>
              <catch event="event.foo">
                <audio src="beep.wav"/>
              </catch>
           </field>
        </form>
      </vxml>
    当抛出一个事件时,则检查该事件被处理的作用域及包含该作用域的所有作用域,根据以下的算法以确定最合适的<catch>元素:
      1、将当前作用域内和包含该作用域的所有作用域内的所有的<catch>元素形成一个列表,先以作用域排序(由当前作用域开始),在每个作用域内再以文档顺序排序。
      2、去掉该列表中于当前抛出的事件不匹配的元素;去掉cond属性值为boolean false的元素。
      3、找出"正确的计数":在该列表的<catch>元素中count属性值最高的,且小于或等于当前的count值的<catch>元素。
      4、选定该列表中计数正确的第一个<catch>元素。
    如果抛出的事件名匹配了<catch>元素中的事件名,则这是一个精确匹配,或是前缀匹配,或者该<catch>元素没有指定event属性。如果<catch>元素event属性值中的事件是所抛出的事件的前缀,则为前缀匹配。点号是前缀的分隔符,点号后面的字符都去掉。空的字符串可以匹配任何事件。例如:
       <catch event="connection.disconnect">
         <prompt>Caught a connection dot disconnect event</prompt>
       </catch>
    在该例子中,事件connection.disconnect前缀匹配事件connection.disconnect.transfer。
       <catch event="com.example.myevent">
         <prompt>Caught a com dot example dot my event</prompt>
       </catch>
    上面的例子中,事件com.example.myevent将前缀匹配事件com.example.myevent.event1., com.example.myevent. 和 com.example.myevent.event1,而事件com.example.myevents.event1则不会被匹配。
       <catch event=".">
         <prompt>Caught an event</prompt>
       </catch>
    上面的例子中,点号将前缀匹配所有的事件(如同<catch>元素没有指定event属性一样)。
    注意,在<catch>元素的选定算法中,文档顺序靠前的<catch>元素的优先权比文档顺序靠后的高。该算法并没有规定,指定的事件越明确的<catch>元素的优先权越高。因此在一般情况下,我们建议,指定的事件越明确的<catch>元素,其文档顺序应越靠前;而越不明确的<catch>元素,其文档顺序应越靠后。例如,我们建议捕捉事件“error.foo”和“error”的文档顺序如下:
       <catch event="error.foo">
         <prompt>Caught an error dot foo event</prompt>
       </catch>
       <catch event="error">
         <prompt>Caught an error event</prompt>
       </catch>
    如果上述的<catch>元素的文档顺序相反,则捕捉事件“error.foo”的<catch>元素永远都不会被执行。
 
五、Default Catch Elements
    如果开发者没有指定对noinput,help,nomatch,cancel,exit和error这几个事件的事件处理,解释器应该隐式的提供这些事件默认的事件处理。
    系统对各种事件和错误默认的事件处理可总结为以下两点:1、是否提供音频作为响应;2、执行什么操作。如果提供音频作为响应,收集播放的内容是依赖于平台的。
事件类型 是否提供音频 执行的操作
cancel 没有reprompt
error 退出解释器
exit 退出解释器
help reprompt
noinput reprompt
nomatch reprompt
maxspeechtimeout reprompt
connection.disconnect 退出解释器
all others 退出解释器
表43:默认的<catch>元素的事件处理
    不同的平台可能有不同的默认提示语。
 
六、Event Types
    事件可分为预定义事件、应用和平台指定的事件,还可分为普通事件(正常情况下发生的事件)和错误事件(非正常情况下发生的事件)。错误事件的命名规则允许使用多级命名。
    浏览器可以抛出一个预定义事件的扩展事件,该扩展事件是以指定的预定义事件名作为前缀的。处理预定义事件的应用是可以共用的,而处理扩展的预定义事件的应用则不能保证它的共用性。例如,如果在加载一个语法文件时检测到一个语法错误,则平台必须抛出“error.badfetch”事件,如果抛出“error.badfetch.grammar.syntax”也是可接受的。
    关于事件的更多的信息,可通过“_message”变量获得(见5.2.2节)。
    预定义的事件有:
    cancel
    用户要求取消播放当前提示语。
    connection.disconnect.hangup
    用户挂机。
    connection.disconnect.transfer
    用户被无条件转接到另一条线路,且不会返回。
    exit
    用户要求退出。
    help
    用户请求帮助。
    noinput
    用户在timeout的时间内没有响应。
    nomatch
    用户有输入,但是和语法不匹配。
    maxspeechtimeout
    用户输入的事件超过了‘maxspeechtimeout’ property的值。
    另外,还有在跳转中产生的错误(见2.4.7.3节),预定义的错误有:
    error.badfetch
    当解释器环境已经解释到某个文档中需要获取一个文档的地方,且获取该文档失败,则解释器环境会抛出该事件。不支持的scheme应用,不对的URI,客户端退出,信息传送错误,timeout,安全违规,不支持的资源类型,资源类型不匹配,文档解析错误和scheme指定的各种错误代码的返回都会导致获取失败。
    如果解释器环境根据环境预取了一个文档,但是后来并不需要这个文档,则不会抛出error.badfetch事件。类似的,如果获取一个音频文件失败,但是该音频有候补的音频或有候补的文本,且获取候补的音频或文本成功,则不会抛出error.badfetch事件。
    当解释器环境将要跳转到一个新的文档时,一直准备抛出error.badfetch事件,直到它能够执行这个新的文档为止。但是,如果抛出事件,也只是在需要该新文档的时候才抛出。在需要该新文档之前是不会抛出的。执行这个新文档是否包括变量初始化是依赖于平台的。
    error.badfetch.http.<response code>
    error.badfetch.protocol.<response code>
    当获取失败时,解释器环境必须用一个具体的事件类型表明是遇到了哪一个特定的HTTP或其他的协议的响应码(response code),RFC2616中定义了HTTP响应码的值。这样对于一个获取失败的文档,应用就可以进行不同的处理。其他协议的响应码的值是依赖于相应的协议的。
    error.semantic
    当在VoiceXML文档中发现运行时(run-time)错误时,抛出该事件。例如取子串越界错误,或引用undefined的变量。
    error.noauthorization
    当应用试图执行一个平台没有授权的操作时,抛出这个事件。例如,呼叫一个非法的电话号码,或呼叫该用户不允许呼叫的号码,或通过依赖于平台的object访问受保护的数据库,或不适当的进入内置语法等。
    error.noresource
    这是一个运行时错误。在执行期间,如果请求的平台资源不可用时,抛出这个事件。
    error.unsupported.builtin
    当平台不支持所请求的内置类型/语法时,抛出这个事件。
    error.unsupported.format
    当平台不支持所请求的资源的格式时,抛出这个事件。例如一个不支持的语法格式,或媒体格式。
    error.unsupported.language
    当平台不支持语音合成或语音识别的语言时,抛出这个事件。
    error.unsupported.element
    当平台不支持给定的元素(该元素是这个技术规范中定义的VoiceXML元素)时,抛出这个事件。例如,如果平台没有实现<transfer>元素,在使用该元素时,必须抛出error.unsupported.transfer事件。这样可以让开发者使用事件处理来适应不同的平台。
    在加载文档时碰到的错误,包括传送错误(没有找到文档、HTTP状态码404等等)和句法错误(没有<vxml>元素等),会导致在调用的文档中抛出一个error.badfetch事件。在加载文档之后,进入FIA的初始化阶段之前出现的错误按照平台指定的方式进行处理。进入FIA的初始化阶段之后出现的错误,在新文档中抛出相应的事件,例如语义错误等。在加载会话的第一个文档时出现的错误的处理方式是依赖于平台的。
    依赖于应用和依赖于平台的事件类型应该使用反转域名的命名规则,以避免命名冲突。例如:
    error.com.example.voiceplatform.noauth
    表示用户在该平台上无权呼出。
    org.example.voice.someapplication.toomanynoinputs
    表示用户没有输入的时间太长了。
    <catch>元素能捕捉特定的事件(cancel),或那些前缀(error.unsupported)相同的事件。

第三节 Executable Content  
 
    可执行内容指的是一段程序逻辑。例如出现在
      ·form item <block>元素中;
      ·<form>元素或input item的<filled>元素中;
      ·事件处理中(<catch>,<help>元素等)。
    可执行元素按照它们的文档顺序被依次执行。如果某个可执行元素产生一个错误,则这个错误马上被抛出。其后的可执行元素就不会被执行了。
    这一节描述的是出现在可执行内容中的元素。
 
一、VAR
    <var>元素用于声明一个变量。它可以出现在任何可执行的内容中,也可以作为<form>元素或<vxml>元素的子元素出现。例如:
       <var name="phone" expr="'6305551212'"/>
       <var name="y" expr="document.z+1"/>
    如果它出现在可执行的内容中,它声明的变量作用域为anonynous,且作用在包含它的<block>,<filled>或<catch>元素中。在这种情况下,只有<var>元素被执行的时候才声明该变量。如果该变量在这个作用域已经声明了,则其后的声明将被看作是赋值,就像在ECMAScript中一样。
    如果<var>元素作为<form>元素的子元素出现,则它声明的变量的作用域为该form的dialog。在这种情况下,在该form的初始化阶段就进行变量声明(详见2.1.6.1节)。<var>元素不是一个form item,因此,它不能被FIA的主循环访问。
    如果<var>元素作为<vxml>元素的子元素出现,它声明的变量的作用域为document;如果该文档是应用根文档,它声明的变量的作用域为application。当文档被初始化的时候就进行变量声明,且初始化是按照文档的顺序进行的。
    它的属性有:
name 保存变量值的变量名。
expr 该变量的初始值(可选的)。如果没有指定该属性,该变量保持它当前的值(如果它当前有值的话);如果没有给定初始值,变量初始值默认为ECMAScript的undefined。
表44:<var>元素的属性
 
二、ASSIGN
    <assign>元素用来给变量赋值:
      <assign name="flavor" expr="'chocolate'"/>
      <assign name="document.mycost" expr="document.mycost+14"/>
    给没有用<var>元素或在<script>元素中的var语句显式声明的变量赋值是非法的。试图给一个没有声明的变量赋值,平台会抛出error.semantic事件。
    注意:如果一个ECMAScript对象已经被正确地初始化(例如“obj”),则它的属性(例如“obj.prop1”)没有显式声明就可以给它赋值(实际上,如果试图声明ECMAScript对象的属性,如声明“obj.prop1”平台会抛出error.semantic事件)。
    <assign>元素的属性:
name 要被赋值的变量名。
expr 要赋给该变量的值。
表45:<assign>元素的属性
 
三、CLEAR
    <clear>元素的作用是重置(清零)一个或多个变量,包括form item。重置form item包括以下的操作:
      1、把该form item变量置为ECMAScript的undefined。
      2、重新初始化该form item的提示语计数器和事件计数器。
    例如:
       <clear namelist="city state zip"/>
    它的属性有:
namelist 要重置的变量清单,它除了可以包括form item也可以包括变量名。如果没有指定,当前form的所有form item都被重置。
表46:<clear>元素的属性
 
四、IF, ELSEIF, and ELSE
    <if>元素用于判断条件逻辑,它可以和<elseif>、<else>搭配使用。
      <if cond="total > 1000">
         <prompt>This is way too much to spend.</prompt>
      </if>
										
     <if cond="amount < 29.95">
        <assign name="x" expr="amount"/>
     <else/>
        <assign name="x" expr="29.95"/>
      </if>
										
      <if cond="flavor == 'vanilla'">
        <assign name="flavor_code" expr="'v'"/>
      <elseif cond="flavor == 'chocolate'"/>
        <assign name="flavor_code" expr="'h'"/>
      <elseif cond="flavor == 'strawberry'"/>
        <assign name="flavor_code" expr="'b'"/>
      <else/>
        <assign name="flavor_code" expr="'?'"/>
      </if>
 
五、PROMPT
    提示语可以<prompt>元素的一般形式出现在可执行内容中,除非不使用<prompt>元素的count属性。特别的,它的cond属性也可用在可执行内容中。提示语可以被封装在<prompt>和</prompt>中,或使用PCDATA表示。只要是<prompt>元素允许出现的地方,使用PCDATA xyz等价于使用<prompt>xyz</prompt>。
      <nomatch count="1">
         To open the pod bay door, say your code phrase clearly. 
      </nomatch>
										
     <nomatch count="2">
        <prompt>
           This is your <emphasis>last</emphasis> chance.
       </prompt>
     </nomatch>
										
      <nomatch count="3">
         Entrance denied.
        <exit/>
     </nomatch>
 
六、REPROMPT
    在处理一个事件的过程中,FIA需要一个<catch>元素对适当的提示语进行排队。因此,在执行完一个<catch>元素后的下一次循环中,FIA一般不会进行正常的选定和提示语排队。然而,有两种情况下,FIA在执行完一个<catch>元素后的下一次循环中,会进行正常的选定和提示语排队:
      1、如果在<catch>元素中执行了<goto>元素或<submit>元素,跳转到另一个dialog,或者执行了一个<return>元素,从一个subdialog中返回,在这些情况下,新的dialog需要保证它的初始提示语保持原样;
      2、如果在<catch>元素中执行了一个<reprompt>元素,要求FIA随后要重新播放提示语。
    在这两种情况中,FIA选定下一个要访问的form item之后,会执行正常的提示语处理,包括选定该form item的提示语,对提示语进行排队,和给该form item的提示语计数器加1。
    例如,下面的例子中的noinput事件处理希望FIA访问下一个form item时,选定并播放它的提示语:
      <field name="want_ice_cream">
        <grammar type="application/srgs+xml" src="/grammars/boolean.grxml"/>
        <prompt>Do you want ice cream for dessert?</prompt>
        <prompt count="2">
          If you want ice cream, say yes.
          If you do not want ice cream, say no.
       </prompt>
       <noinput>
          I could not hear you.
          <!-- Cause the next prompt to be selected and played. -->
         <reprompt/>
       </noinput>
     </field>
    可能的一个对话流程:
      C: Do you want ice cream for dessert?
      H: (silence) 
      C: I could not hear you.
      C: If you want ice cream, say yes. If you don't want ice cream, say no.
      H: (silence) 
      C: I could not hear you.
      C: If you want ice cream, say yes. If you don't want ice cream, say no.
      H: No.
    如果该例子中没有<reprompt>元素,上面的流程变为如下所示:
      C: Do you want ice cream for dessert?
      H: (silence) 
      C: I could not hear you.
      H: (silence) 
      C: I could not hear you.
      H: No.
    注意,上面的例子中之所以略过了提示语选择阶段,是因为在执行完一个<catch>元素后(没有执行<reprompt>元素,或没有通过<goto>、<submit>、<return>元素跳转到另一个dialog),被FIA选定的该form item的提示语计数器并没有加1。
    同时注意,执行一个<catch>元素后(没有执行<reprompt>元素,或没有通过<goto>、<submit>、<return>元素跳转到另一个dialog),FIA选定的下一个要访问的form item的提示语选定阶段也会被略过,即使该form item和前一个被选定的form item不是同一个。
    <reprompt>元素在<catch>元素之外是不会起作用的。
 
七、GOTO
    <goto>元素用于:
      1、跳转到当前form的另一个form item;
      2、跳转到当前文档的另一个dialog;
      3、跳转到另一个文档。
    要跳转到另一个form item,使用next属性,或使用expritem属性,如果该form item名可以通过ECMAScript表达式计算得到的话:
      <goto nextitem="ssn_confirm"/>
      <goto expritem="(type==12)? 'ssn_confirm' : 'reject'"/>
    要跳转到同一个文档的另一个dialog,使用next属性,或使用expr属性指定一个URI段:
      <goto next="#another_dialog"/>
      <goto expr="'#' + 'another_dialog'"/>
    要跳转到另一个文档使用next属性,或使用expr属性指定一个URI:
      <goto next="http://flight.example.com/reserve_seat"/>
      <goto next="./special_lunch#wants_vegan"/>
    URI可以是当前文档的绝对或相对的URI。要指定下一个文档开始的dialog,可以使用对应于该dialog的id属性值的URI段。如果没有指定URI段,则以要跳转到的文档的第一个dialog为开始的dialog。
    注意,跳转到当前文档的另一个dialog会导致旧的dialog变量丢失,即使是一个dialog跳转到它自己也会丢失。同样的,使用相对或绝对的URI跳转到另一个文档,也会丢失文档变量,即使是一个文档跳转到它自己也会丢失。然而,当跳转到一个带有段标识符的空的URI引用时,文档变量不会丢失。例如下面两个语句在URI为http://someco.example.com/index.vxml的文档中有不同的行为:
      <goto next="#foo"/>
										
      <goto next="http://someco.example.com/index.vxml#foo"/>
    根据RFC2396,段标识符(“#”后面的部分)不是URI的一部分,到一个空的URI引用加上段标识符的跳转永远都不会获取到一个新的文档。因此,第一条语句中的“#foo”时一个带有段标识符的空的URI引用,它的文档变量不会丢失。在第二条语句中,“#foo”是一个绝对URI的一部分,该跳转会导致文档变量的丢失。如果想要在多文档中保存数据,请把数据保存在应用根文档中。
    在<goto>元素的next或expr属性中,URI引用(详见RFC2396)指定要跳转到的dialog,如果这个URI引用包含一个绝对或相对的URI,该URI可以包含一个查询串,则FIA获取该URI,并且在目标文档中寻找相应的dialog。
    如果该URI引用只包含一个段(即没有绝对或相对的URI),则没有任何文档被获取,FIA在当前文档中寻找相应的dialog。
    URI引用中的段,如果有的话,以要跳转到的dialog命名,如果URI引用中没有段,则选定目标文档的第一个dialog。
    如果要跳转到的form item、dialog或文档不可用(即该form item、dialog或文档不存在),必须抛出error.badfetch事件。注意,对于在dialog或文档跳转时出现错误,处理错误的作用域是依赖于平台的;对于在form item之间跳转时出现的错误,事件在dialog的作用域内处理。
    <goto>元素的属性:
next 要跳转到的URI。
expr 一个ECMAScript表达式 ,其结果值为要跳转到的URI。
nextitem 当前form 中下一个要访问的form item名。
expritem 一个 ECMAScript表达式,其结果值为当前form中下一个要访问的form item名。
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>。
表47:<goto>元素的属性
    必须正确地指定属性“next”、“expr”、“event”和“eventexpr”中的一个,否则会抛出error.badfetch事件。
 
八、SUBMIT
    <submit>元素用于提交信息给web服务器,然后跳转到web服务器响应后返回的文档。和<goto>元素不一样的是,<submit>元素可以通过HTTP GET或POST请求提交一个变量列表到文档服务器。例如可以提交一组form item变量到服务器:
      <submit next="log_request" method="post"
         namelist="name rank serial_number"
         fetchtimeout="100s" fetchaudio="audio/brahms2.wav"/>
    <submit>元素的next或expr属性指定了要跳转到的dialog。该URI每次都要被获取,即使它只包含了一个段。在URI只包含一个段的情况下,请求的URI就是当前文档的基本URI。因此,下面的两个元素有完全不同的效果:
      <goto next="#get_pin"/>
										
      <submit next="#get_pin"/>
    注意:虽然URI总是要被获取,并且跳转到目标文档,但是通过缓存,还是能够满足某些<submit>元素请求的。例如,如果web服务器在响应时提供了一个显式的过期时间,就可能发生这种情况。
    如果要跳转到的dialog或文档是非法的(即该dialog或文档不存在),必须抛出一个error.badfetch事件。注意:对于那些在dialog或文档跳转时出现的错误,在哪个作用域内处理它们是依赖于平台的。
    <submit>元素的属性有:
next 要引用的URI。
expr ECMAScript表达式,它的结果值为要引用的URI。
namelist 要提交的变量名列表。默认是提交所有有命名的input item。如果指定了namelist属性,它可以包含一个或多个变量名,以空格隔开。在VoiceXML和ECMAScript中声明的变量都能被提交。
method 请求的方法:get(默认的)或post。
enctype 被提交的文档的媒体编码类型,默认为application/x-www-form-urlencoded 。解释器也必须支持multipart/form-data ,也可以支持其他的编码类型。
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>。
表48:<submit>元素的属性
    必须正确的指定属性next或expr中的一个,否则会抛出error.badfetch事件。
    当一个ECMAScript变量被提交给服务器时,它先被转换成一个字符串才被提交。VoiceXML目前还没有定义一种提交ECMAScript对象的机制,将来会定义这种机制。一种变通的方法是,开发者可以显式的提交对象的属性,例如“date.month date.year”。
    如果<submit>元素包含的变量引用了一个录制的音频,但是没有包含multipart/form-data的ENCTYPE的话,VoiceXML目前还没有规定这种行为。试图在URI中对大量的数据编码显然是不合实际的。
 
九、EXIT
    <exit>把控制返回给解释器环境,由解释器环境决定下一步做什么。
      <exit/>
    该元素和<return>元素的不同之处在于它终止了所有加载的文档,而<return>则是从一个<subdialog>调用中返回。如果<subdialog>调用了一个新的文档(或应用),则<return>会终止被调用的文档,控制返回到<subdialog>元素继续执行。
    注意,一旦<exit>把控制返回给解释器环境,解释器环境就可以做它想做的操作。例如,它可以给用户播放上一级<menu>元素中的提示语,或者挂机,或者把用户转接到人工坐席。
    它的属性有:
expr 一个ECMAScript表达式,该表达式的值就是要返回的值(如“0”,“oops!”或“field1”)。
namelist 要返回给解释器环境的变量名清单。默认是返回0个变量,这样意味着解释器环境将接收到一个空的ECMAScript 对象。
表49:<exit>元素的属性
    可以正确地指定属性“expr”和“namelist”中的一个,否则,会抛出error.badfetch事件。
    <exit>元素不会抛出一个“exit”事件。
 
十、RETURN
    <return>元素用于结束一个subdialog的执行,并把控制和数据返回给调用它的dialog。
    它的属性有:
event 要返回并抛出的事件。
eventexpr ECMAScript表达式。其结果值为抛出的事件。它的作用是从subdiaolog中返回,并抛出该事件 。
message 有关被抛出的事件的信息。在<catch>元素中,可通过“_message”变量取得该信息,见5.2.2节。
messageexpr ECMAScript表达式。其结果值为有关被抛出的事件的信息。
namelist 要返回的变量名。默认为返回0个变量,即调用该subdialog的dialog将得到一个空的ECMAScript 对象 。
表50:<return>元素的属性
    可以正确的指定属性“event”,“eventexpr”或“namelist”中的一个,否则会抛出一个error.badfetch事件。可以正确的指定属性“message”或“messageexpr”中的一个,否则会抛出一个error.badfetch事件。
    当从一个subdialog中返回,一个事件在调用的地方被抛出,或者数据作为一个ECMAScript对象被返回,该对象的属性对应于subdialog中的<return>元素的namelist属性值。如果不是在subdialog中执行,却碰到<return>元素,则会抛出一个语义错误。
    下面的例子展示了,当subdialog不能获得一个可识别的结果时,一个nomatch事件通过subdialog在调用它的dialog中抛出。
      <?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>
           <subdialog name="result" src="#getssn">
              <nomatch>
                <!-- a no match event that is returned by the  subdialog indicates
                     that a valid social security number could not be matched. -->
                <goto next="http://myservice.example.com/ssn-problems.vxml"/>
              </nomatch>
										
             <filled>
               <submit namelist="result.ssn"
                  next="http://myservice.example.com/cgi-bin/process"/>
             </filled>
           </subdialog>
         </form>
        <form id="getssn">
          <field name="ssn">
          <grammar src="http://grammarlib/ssn.grxml" type="application/srgs+xml"/>
           <prompt> Please say social security number.</prompt>
           <nomatch count="3">
             <return event="nomatch"/>
           </nomatch>
           <filled>
             <return namelist="ssn"/>
           </filled>
          </field>
        </form>
      </vxml>
    subdialog中的nomatch事件处理在第三次匹配失败时被触发,然后从subdialog中返回,并在调用他的dialog中抛出该事件。在这种情况下,调用的dialog将执行它自己的nomatch事件处理,通过<goto>元素跳转到另一个文档,而不是执行<filled>操作。在一般的情况下,如果得到一个识别结果,就会执行该<subdialog>元素中的<filled>操作,该识别结果可通过result.ssn访问。
 
十一、DISCONNECT
    它的作用是使解释器环境断开和用户之间的链接,此时,解释器环境将抛出connection.disconnect.hangup事件,它可以被捕获,以做一些清除的处理。
      <disconnect/>
 
十二、SCRIPT
    <script>元素允许在VoiceXML脚本中使用一段客户端的脚本语言代码,它和HTML的<SCRIPT>元素类似。例如下面的例子中<script>元素用于计算一个数的阶乘:
      <?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">
       <script> <![CDATA[
             function factorial(n)
             {
              return (n <= 1)? 1 : n * factorial(n-1);
             }
        ]]> </script>
										
       <form id="form">
          <field name="fact">
            <nomatch>
             <grammar type="application/srgs+xml" src="/grammars/number.grxml"/>
             <prompt>
                Tell me a number and I'll tell you its factorial.
             </promptd>
             <filled>
               <prompt>
                 <value expr="fact"/> factorial is
                 <value expr="factorial(fact)"/>
               </prompt>
             </filled>
           </field>
         </form>
      </vxml>
    <script>元素可以出现在<vxml>元素和<form>元素中,或者出现在可执行的内容中(如<filled>,<if>,<block>,<catch>或<catch>元素的快捷标记)。在文档被装载后,<vxml>元素中的<script>元素和<var>元素都按照它们的文档顺序被依次求值。每次执行到<form>元素,该form中的<script>元素和<var>元素及form item 变量也是按照它们的文档顺序被依次求值。和其他的可执行元素一样,当在可执行的内容中碰到<script>元素时,都会执行它。
    <script>元素的属性有:
src 如果脚本是外部的,则该属性指定了该外部脚本的URI。
charset 属性src指定的脚本的字符编码。平台必须支持ISO/IEC 10646的UTF-8 和 UTF-16编码,也可以支持其他的编码,如IANA中定义的。默认为UTF-8。
fetchhint 见6.1节。它默认为documentfetchhint <property>。
fetchtimeout 见6.1节。它默认为fetchtimeout <property>。
maxage 见6.1节。它默认为documentmaxage <property>。
maxstale 见6.1节。它默认为documentmaxstale <property>。
表51:<script>元素的属性
    必须指定一个src属性或一个联机脚本中的一个(不是两个都指定),否则,会抛出error.badfetch事件。
    VoiceXML中的<script>元素没有type属性(这一点和HTML的<SCRIPT>元素不一样),ECMAScript是VoiceXML必须的脚本语言。
    每个<script>元素在它的父元素的作用域内被执行,即它没有自己的作用域。例如在<script>元素用var语句声明的变量的作用域为该<script>元素的父元素(用ECMAScript的术语来说,就是"变量对象"为包含<script>元素的元素的当前作用域)。
    下面的例子中<block>包含有<script>元素,并初始化该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> 
          <var name="hours"/>
          <var name="minutes"/>
          <var name="seconds"/>
          <block>
            <script>
              var d = new Date();
              hours = d.getHours();
              minutes = d.getMinutes();
              seconds = d.getSeconds();
            </script>
           </block>
           <field name="hear_another">
             <grammar type="application/srgs+xml" src="/grammars/boolean.grxml"/>
               <prompt>
                 The time is <value expr="hours"/> hours,
                 <value expr="minutes"/> minutes, and
                 <value expr="seconds"/> seconds.
               </prompt>
               <prompt>Do you want to hear another time?</prompt>
              <filled>
                <if cond="hear_another">
                  <clear/>
                </if>
              </filled>
            </field>
         </form>
      </vxml>
    <script>元素的内容在和<var>元素一样的作用域内被求值(见5.1.2和5.3.1节)。
    由于设置了ECMAScript的作用域链,因此,无论是<var>元素声明的变量,还是在<script>元素中声明的变量,它们的作用域都是包含该<var>元素或<script>元素的元素的作用域。例如,在<form>的<script>元素中声明的变量的作用域为dialog,它能够作为一个作用域为diaolog的变量被访问:
      <?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>
          <script>
             var now = new Date(); <!-- this has a dialog scope-->
           </script>
           <var name="seconds" expr="now.getSeconds()"/> <!-- this has a dialog scope-->
           <block>
             <var name="now" expr="new Date()"/> <!-- this has an anonymous scope -->
             <script>
                var current = now.getSeconds();<!-- "now" in the anonymous scope -->
                var approx = dialog.now.getSeconds(); <!-- "now" in the dialog scope -->
             </script>
           </block>
         </form>
      </vxml>
    所有的变量在被ECMAScript脚本或VoiceXML元素引用之前都必须声明,详见5.1.1节。
 
十三、LOG
    <log>元素让应用程序可以产生日志或调试信息,这些信息能够用来帮助开发者开发程序,或进行执行后的程序性能分析。
    <log>元素可以包含文本(CDATA)和<value>元素的任意组合,产生的信息由文本和<value>元素的cond属性值串联起来组成。
    信息的显示和记录方式是依赖于平台的,lable属性的用法也是依赖于平台的。
    <log>元素中的ECMAScript表达式根据它们在文档中的顺序求值,使用<log>元素不应该对文档的解释产生任何的副作用。
      <log>The card number was <value expr="card_num"/></log>
    <log>元素的属性:
label 一个字符串,例如它可以用来表明该<log>元素的目的。
expr 一个ECMAscript表达式,它的结果值为一个字符串。
表52:<log>元素的属性
posted on 2006-09-16 22:50 铁观音 阅读(907) 评论(0)  编辑 收藏 引用 所属分类: VoiceXML2.0规范