VXML Grammars, Scope, and Event Handlers

        构建健壮的语音应用程序意味着在有经验的用户和小白用户的需求之间取得平衡。有经验的用户通常希望跳转到他们已经知道的选项;小白用户通常希望他们能得到相应的帮助。与大多数现代编程语言一样,Voice XML提供了一个结构化的应用程序框架,它支持事件、处理程序和范围规则,使开发人员能够微调语音应用程序在不同上下文中的响应方式。

        了解VXML基础知识(如dtmf、field等)可以帮助快速构建有用且功能强大的语音应用程序。然而,有时需要超越这些基础知识,交付更复杂、更鲁棒性和响应更快的语音应用程序。例如,用户可能希望提供常规的以及特定于上下文的帮助消息,或者允许有经验的用户中断对话框并跳转到特定的选项, 而不被提示。为了编写允许这种跨对话框跳转的应用程序,Voice XML支持类似于编程语言中的作用域规则。在Voice XML中,语法可以定位在字段、表单或文档级别。此外,我们还可以通过将多个文档组合为一个应用程序来响应整个文档集合中的输入。具体的编辑要点需要注意下面几个方向:

Barging in with bargein

       默认情况下,VXML应用程序允许用户直接打断对话提示,进行输入。这种中断能力是由VXML元素中的barge in属性控制的,这有利于经常使用的用户,他们可以根据需要快速获取所需的信息,从而绕过冗长的提示音。但是,开发人员可以选择性地禁用bargein,以确保用户监听完整的信息性消息或广告。此外,可以禁用bargein以防止虚假的后台对话触发活动语法。

下图演示了如何禁用bargein(第4行)并强制用户收听广告。由于例1中的表单关闭了bargein,其作用范围仅限于当前字段,所以文档中可能出现的其他对话框不会关闭bargein。如果在文档级别关闭bargein将默认关闭文档中所有对话的bargein。

1 <vxml version="2.1">
2  <form id="main">

3  <!--inside the form we disable bargein for this dialog -->
4  <property name="bargein" value="false"/>

5  <!-- play an ad -->
6  <block>
7   <audio src="http://www.zorko.com/ads/paynow.wav"/>
8  </block> 

9 <!-- dialog -->
10 <field name="city">
11  <prompt>What city are you calling from?</prompt>
12  <grammar src="city.grammar"/>
13  </field>
14  </form>
15 </vxml>

当bargein为真时,用户可以直接跳出一个对话框,并快速跳转到其他对话框。为了实现这个功能,需要激活多个语法,以便在有语音或dtmf输入匹配时跳转对话字段。

先看一个简单的例子,说明如何在单个文档中完成这项工作,然后再看多文档操作。

图2演示了包含多个对话框的文档的语法范围。示例代码使用VXML link元素,该元素使我们能够定义一个目标对话框和一个语法,该语法定义将跳转的对话框Id。链接元素的结构如下:

<link next="#mydialog">
   <grammar mode="voice">
    <!--grammar goes here -->
  </grammar>   
 </link>

在例2中,link元素显示为vxml元素的一个子元素,作用范为整个文档。这意味着在文档中包含的任何菜单或表单中,与其中一个链接语法的匹配将跳转至目标对话框。

此示例还包含两个链接元素:一个将使我们快速转换到baseball菜单,另一个将带我们转到id=“mets”的表单。

       在第13行中,link元素包含一个用于单个单词棒球的语法。请注意,我们的示例包含两个链接元素:一个用于转换到“baseball”对话框(第10行),另一个用于转换到“mets”对话框(第18行)。

       还要注意,第18行的链接包含两个语法:一个是语音,另一个是dtmf。因此,如果用户在任何时候说“mets”或“New York mets”或按9,均会跳转到id为“mets”的表单。

 

1  <?xml version="1.0" encoding="UTF-8"?>
2  <!DOCTYPE vxml SYSTEM "http://www.w3.org/TR/voicexml20/vxml.dtd">
3  
4  <vxml version = "2.0" xmlns=’http://www.w3.org/2001/vxml’
5     xmlns:xsi=’http://www.w3.org/2001/XMLSchema-instance’
6     xsi:schemaLocation=’http://www.w3.org/2001/vxml 
7     http://www.w3.org/TR/voicexml20/vxml.xsd’>
8   
9   
10   <link next="#baseball">
11    <grammar mode="voice">
12     <rule id="linkbaseball" scope="public">
13      baseball
14     </rule>
15    </grammar>   
16   </link>
17   
18   <link next="#mets">
19     <grammar>
20      <rule id="linkmets" scope="public">
21       <one-of>
22        <item>mets</item>
23        <item>new york mets</item>
24       </one-of>
25      </rule>
26     </grammar> 
27     
28     <grammar mode="dtmf" >
29      <rule id="linkmets2" scope="public">9</rule>
30     </grammar>
31     
32   </link>
33   
34   
35   <menu id="mainmenu" dtmf="true">
36    <prompt>
37     Welcome to the info hotline. If you know the category you want, 
38     you may say it at any time.
39     <enumerate>
40      For <value expr="_prompt"/>, press <value expr="_dtmf"/> 
41     </enumerate>
42    </prompt>
43  
44    
45    <choice next="#sports">sports</choice> 
46    <choice next="#weather">weather</choice> 
47   </menu> 
48  
49  <menu id="sports">
50   <property name="inputmodes" value="dtmf"/>
51   <prompt>
52   For baseball press 1, For football press 2, For soccer
53   press 3.
54   </prompt>
55   <choice dtmf="1" next="#baseball"/>
56   <choice dtmf="2" next="#football"/>
57   <choice dtmf="3" next="#soccer"/>
58  </menu>
59   
60  
61  <form id="weather">9
62   <block> You have reached the weather line. Whether it’s cold,
63   or whether it’s hot, we’re going to have weather,
64   whether or not.
65   </block> 
66  </form>
67  
68  <menu id="baseball">
69   <property name="inputmodes" value="dtmf"/>
70   <prompt>
71   For yankees press 1, For mets press 2, For giants press 3.
72   </prompt>
73   <choice dtmf="1" next="#yankees"/>
74   <choice dtmf="2" next="#mets"/>
75   <choice dtmf="3" next="#giants"/>
76  </menu>
77  
78  <form id="soccer">
79   <block> you have reached the soccer hotline.
80   </block>
81  </form>
82  
83  <form id="football">
84   <block> you have reached the football hotline.
85   </block> 
86  </form>
87  
88  <form id="mets">
89   <block> The mets are contenders for the world series. 
90   </block> 
91  </form> 
92  
93  <form id="yankees">
94   <block> George Stein Brenner rules his roost.
95   </block> 
96  </form> 
97  
98  <form id="giants">
99   <block> Barry Bonds has now hot more home runs than Hank Aaron.
100  </block> 
101 </form> 
102 
103 </vxml>

在例2中,所有的menu和form都包含在同一个文档中,因此我们对link元素的定位(使用document scope)确保链接语法在所有对话框中都是可操作的。但是,如果我们的菜单和表单设置为单独的文档,则在转换到另一个文档后,快捷文档链接语法将不再可用。为了解决这个问题,以便语法、变量和属性在一系列单独的文档中保持可见,Voice XML支持应用程序的概念。

Multiple Document Applications

Voice XML多文档应用程序是围绕单个根文档和一个或多个叶子文档构建的。根文档中定义的任何语法或变量对叶子文档都是可见的。若要设置为使多个文档作为一个应用程序协同工作,首先应选择一个文档作为应用程序根文档;其他文档被视为叶子文档。要被视为根文档,只需要另一个文档在<vxml>元素中将其命名为应用程序文档。

       当应用程序配置了根和叶子文档时,每次加载叶子文档时,都会检查根文档是否也已加载。否则,服务器首先加载根目录。在服务器加载属于不同应用程序的文档之前,该应用程序的根文档将一直保留在作用域中。加载叶子文档时,会导致根文档也被加载,但不会执行根文档中的任何对话框,执行将从叶子文档中开始。

例3演示了一个包含根文档和两个叶子文档的多文档应用程序。

   根文档,myroot.vxml

1  <?xml version="1.0" encoding="UTF-8"?>
2  <vxml xmlns="http://www.w3.org/2001/vxml"
3   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
4   xsi:schemaLocation="http://www.w3.org/2001/vxml 
5    http://www.w3.org/TR/voicexml20/vxml.xsd"
6    version="2.0">
7   <var name="app" expr="’world’"/>
8   
9   <link next="baseball.vxml">
10    <grammar type="application/srgs+xml" root="root" version="1.0">
11     <rule id="root" scope="public">baseball</rule>
12   </grammar>
13   </link>
14  </vxml>

叶子文档,mainmenu.vxml

16  <?xml version="1.0" encoding="UTF-8"?>
17  <vxml xmlns="http://www.w3.org/2001/vxml" 
18   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
19   xsi:schemaLocation="http://www.w3.org/2001/vxml 
20   http://www.w3.org/TR/voicexml20/vxml.xsd"
21   version="2.0" application="myroot.vxml">
22  
23   <menu id="mainmenu" dtmf="true">
24    <prompt>
25     Welcome to the info <value expr="app"/> hotline. 
26     If you know the category you want, 
27     you may say it at any time.
28     <enumerate>
29      For <value expr="_prompt"/>, press <value expr="_dtmf"/> 
30     </enumerate>
31    </prompt>
32  
33    <choice next="#sports">sports</choice> 
34    <choice next="#weather">weather</choice> 
35   </menu> 
36  
37  <menu id="sports">
38   <property name="inputmodes" value="dtmf"/>
39   <prompt>
40   For baseball press 1, For football press 2, For soccer 
41    press 3.
42   </prompt>
43   <choice dtmf="1" next="baseball.vxml"/>
44   <choice dtmf="2" next="#football"/>
45   <choice dtmf="3" next="#soccer"/>
46  </menu>
47   
48  
49  <form id="weather">
50   <block> you have reached the weather it rains or not hotline
51   </block> 
52  </form>
53  
54  <form id="football">
55   <block> you have reached the football, kick kick hotline
56   </block> 
57  </form>
58  
59  <form id="soccer">
60   <block> you have reached the soccer, push push hotline
61   </block> 
62  </form>
63  
64  
65  </vxml>

叶子文档,baseball.vxml

66  <?xml version="1.0" encoding="UTF-8"?>
67  <vxml xmlns="http://www.w3.org/2001/vxml"
68   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
69   xsi:schemaLocation="http://www.w3.org/2001/vxml 
70   http://www.w3.org/TR/voicexml20/vxml.xsd"
71   version="2.0" application="myroot.vxml">
72  
73  
74  <form>
75   <block>welcome to baseball news. brought to you by
76    the info <value expr="app"/> hotline.
77    </block>
78  </form>
79  
80  </vxml>

在例3中,mainmenu.vxml的初始加载(第16行)强制加载myroot.vxml(第1行)。这将创建应用程序变量app(第7行)并定义一个链接(第9行),每当用户说“basketball”时,该链接将强制转换到basketball.vxml。当应用程序启动时,用户会听到主菜单对话框。

在这个示例对话框中,用户跳起来听关于basketball的内容。

S: Welcome to the info world hotline. If you know the category you want, you may say it at    any time. For sports, press 1. For weather, press 2.
U: Baseball.
S: Welcome to baseball news, brought to you by the info world hotline.

注意,当转换到basketball.vxml时,根文档(第7行)中定义的变量app可用(第76行)。还要注意<vxml>元素(第2-6行)没有指定应用程序属性。在<vxml>元素的application属性(第21行和第71行)中,由一个叶子文档来引用它的应用程序文档。

如果加载的文档未指定应用程序属性,则此文档将成为新应用程序的根文档。

Multidocument Transitions

在多文档应用程序中,一次最多加载两个文档:应用程序根文档和应用程序叶子文档。当使用<choice>、<goto><link>或<submit>元素从一个文档转换到另一个文档时,一些转换将在应用程序中进行,而另一些则可能设置新的应用程序上下文。

现有应用程序的保留或新根上下文的初始化将取决于转换的类型。可能性包括:

应用程序中的根到叶:当前文档是根文档(没有应用程序属性)并且目标文档包含引用当前文档的应用程序属性时,在同一应用程序中发生根到叶转换。发生这种情况时,应用程序根上下文将被保留。

应用程序中的叶到叶:当前文档是叶子文档并且目标文档的应用程序属性值解析为根文档的URI时,在同一应用程序中发生叶到叶转换。将保留应用程序根上下文。

应用程序中的叶到根:当前文档是叶子文档而目标文档的URI是根文档时,同一应用程序中的叶到根转换发生。

根到根:当前文档是根文档而目标文档是根文档时,会发生根到根的转换;也就是说,不再保留应用程序属性。

转换到另一个应用程序的叶:当加载的文档包含不是当前根文档的应用程序属性时,将发生到新应用程序的转换。这将导致加载新的根文档和新的叶文档。

Throwing and Catching Events

基本的事件处理。当用户没有响应、请求帮助或没有以应用程序理解的方式响应时,解释器会以特定于平台的默认值响应,例如:输入不匹配时,反馈“我不理解您所说的话”。

前面的示例演示了开发人员如何通过在字段、窗体、文档或应用程序级别提供<noinput>、<help>或<nomatch>元素来重写此默认行为。例如,考虑没有响应的情况。如果我们提供一个<noinput>元素,如下所示,用户将收到一个提示:“您一直没有输入,请输入账号”:

<catch event=“noinput”>您一直没有输入,请输入账号</noinput>

不难发现Voice XML是基于事件的,很像java Swing这样的编程框架。默认情况下,符合Voice XML的平台为noinput、help、nomatch、cancel、exit和error事件提供隐式catch处理程序(即直接写noinput)。如果处理程序是由开发人员提供的,则它们会覆盖默认值。下表总结了预定义系统事件的catch处理程序的默认系统行为。

下例是对多文档catch元素操作,具体如下:

<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="nomatch noinput" count="5"> 
    <prompt>Security violation! The f b i is being notified.</prompt>  
  </catch>  
  
  
<form id="getData">
  <catch event="nomatch noinput" count="4"> 
    <prompt>You are now in big, big, trouble. </prompt>  
  </catch> 

 <field name="user_id" type="digits"> 
  <prompt>What is your numeric user I D</prompt> 
 </field>
 
 <field name="password"> 
  <prompt>What is the code word?</prompt> 
  <grammar version="1.0" root="root">
   <rule id="root" scope="public">bingo</rule>
  </grammar>
  
  <help>It is the name of a popular multi-player game.</help> 
  
  <catch event="nomatch noinput" count="3"> 
   <prompt>Security violation! You are in big trouble.</prompt> 
  </catch> 
  
 </field> 
 
</form>
</vxml>

下面的示例对话框演示了多个catch处理程序的触发:

S: What is your numeric user I D
U: 1224
S: What is the code word?
U: sassafrass
S: I did not understand what you said <default platform response>
S: What is the code word?
U: monkey
S: I did not understand what you said <default platform response>
S: What is the code word?
U: zorro
S: Security violation! You are in big trouble. <catch with count = 3>
S: What is the code word?
U: mellow yellow
S: You are now in big, big, trouble. <catch with count = 4>
S: What is the code word?
U: haricot vert
S: Security violation! The f b i is being notified. <catch with count = 5>

在前面的对话中,当抛出nomatch事件时,将检查处理该事件的作用域及其作用域,以找到最符合条件的catch元素。

当前作用域和所有封闭作用域(表单项、表单、文档、应用程序根文档、解释器上下文)中的所有捕获首先按作用域排序(从当前作用域开始),然后按文档顺序在每个作用域中排序。对于具有与抛出的事件匹配的事件名称的捕获,将选择具有匹配计数的捕获。

在处理多个事件时,可以使用catch元素的特殊变量event编写一个catch处理程序,该变量包含抛出的事件的名称。例如,以下catch元素处理两种类型的事件:

<catch event="event.zorkon.foo event.zorkon.bar">
 <if cond="_event==’event.zorkon.foo’">
  <!-- Play event.zorkon.foo audio -->
  <audio src="foo.wav"/>
 <else/>
  <!-- Play event.zorkon.bar audio -->
  <audio src="bar.wav"/>
 </if>
 <!-- Continue with common handling for either event -->
</catch>

检查事件变量会根据抛出的事件选择要播放的音频。这里将为event.zorkon.foo事件播放foo.wav文件。将为event.zorkon.bar事件播放bar.wav文件。catch元素的其余部分也可能包含两种事件类型通用的可执行内容。

此外,catch元素的匿名变量作用域还包括特殊变量_message,它包含来自相应<throw>元素的消息字符串的值。例如,如果我们用以下方式抛出事件:

<throw event="com.zorkon.event.foo" message="strange input received"/>

会收到如下

<catch event="com.zorkon.event.foo">
. . .
 <value expr="_message">
. . .
</catch>

Application-Specific Events

现在让我们看看应用程序如何抛出自己的特定的事件来定制响应。在下面的例子中,当boss打电话给他的手机(214.322.6666)时,我们想采取特殊的措施,并且不能调用代码来访问他的数据

1  <vxml version="2.0" xmlns="http://www.w3.org/2001/vxml" 
2   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
3   xsi:schemaLocation="http://www.w3.org/2001/vxml 
4    http://www.w3.org/TR/voicexml20/vxml.xsd">
5    
6    
7    <catch event="com.zorkon.bossHasProblem"> 
8      <prompt>Sir, we are so sorry you are having trouble. 
9        Some one will contact you shortly.</prompt> 
10     <submit next="com.zorkon/bossproblem.jsp"/>   
11     <exit/>   
12   </catch>  
13   
14   
15  <form id="getData">
16  
17   <field name="user_id" type="digits"> 
18    <prompt>What is your numeric user I D</prompt> 
19   </field>
20   
21   <field name="password"> 
22    <prompt>What is the code word?</prompt> 
23    <grammar version="1.0" root="root">
24    <rule id="root" scope="public">bingo</rule>
25    </grammar>
26    
27    <nomatch>
28    <if cond="session.callerid == ’2143226666’">
29      <throw event="com.zorkon.bossProblem"/>
30    <else/>
31       <throw event="com.zorkon.userProblem"/>
32    </if>
33    </nomatch>
34    
35   <help>It is the name of a popular multi-player game.</help> 
36   
37   <catch event="noinput com.zorkon.userProblem"> 
38    <prompt>Security violation! You are in big trouble.</prompt> 
39   </catch> 
40   
41   </field> 
42   
43  </form>
44  </vxml>

在上例中,我们通过内置的变量session.callerid使用对boss电话的先验知识来决定抛出哪个事件。我们处理nomatch事件(第27行)以捕获语法输入错误,然后抛出两个特定于应用程序的事件之一,com.zorkon.bossProblem(第29行)或com.zorkon.userProblem(第31行),具体取决于呼叫是从老板的电话还是从其他地方传入。注意,我们不需要做任何特殊的事情来创建自己的应用程序事件。所需的只是为我们要引发的事件命名,如下所示:

<throw event="com.zorkon.bossProblem"/>

Event Names and Prefix Matching

事件命名和匹配规则

在事件名称(例如com.zorkon.bossProblem)中使用"."不仅使事件可读,名称中的点还相当于定义了一个层次结构,该层次结构可用于为各种事件提供处理程序。例如,当catch元素事件 属性指定要抛出的事件的全名的标记前缀时,会发生前缀匹配。例如,以下将匹配zorkon.disconnect.transfer, zorkon.disconnect.drop或任何以zorkon.disconnect开头的事件 :

<catch event="zorkon.disconnect">
  <prompt>Caught a connection dot disconnect event</prompt>
</catch>

最简单的方法就是简单地指定“.”,如下所示,它匹配所有事件(没有事件属性的<catch>也是如此 ):

<catch event=".">
  <prompt>Caught an event</prompt>
</catch>

      当使用事件前缀来捕获事件时,需要特别注意的是,catch元素优先选择文档中较早出现的catch元素,而不是较晚出现的catch元素。不太具体。因此,建议按从更具体到较不具体的顺序指定捕获元素。例如,应该按以下顺序 为“ error.foo”和“ error”指定catch元素:

<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”将永远不会被执行,因为 event=“error”将总是匹配优先于“error.foo”。

总结

Voice XML为围绕语法和事件构建复杂的模块化应用程序提供了一个具有范围规则的框架。基于字段、表单、文档和应用程序的层次结构,开发人员可以控制语法、变量、事件和属性的可见性。通过定义特定于应用程序的事件并将其抛出层次结构堆栈,开发人员可以定义跨多个文档和表单的相同行为。我们对Voice XML的了解越深入,就越能看到它与成熟的现代编程语言的相似之处。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
找了很久的VoiceXml开发工具,小巧而实用,由华为开发,希望对大家有用。   VoiceXML是建立于XML 语言规范基础之上,是一种应用于语音浏览的标记语言。利用VoiceXML可以建立基于WEB的语音应用和服务。本文简要描述了VoiceXML规范及相关术语,并给出了一种基于VoiceXML的语音与数据集成模型,它主要由语音浏览器、语音识别、语音合成和VoiceXML网关等部分组成。应用该模型,可以方便地建立各种基于WEB的语音应用系统。随着电子商务、客户服务等信息服务的普遍化,交互式语音应答系统(IVR ,Interactive Voice Response)在各种商业系统中的应用越来越广泛。然而这种语音交互方式存在以下缺点:(1)移植性、灵活性差;(2)在实际系统上做应用开发的难度很大,特别是涉及到话音流程的编写及调试问题;(3)无法综合利用现在的WEB资源。而将IVR系统Internet化,可以增加系统可重用的机会,降低成本,这必将成为今后语音应用的一种主要趋势。另一方面,到目前为止,人们从Internet获取各种资源时,还只能是借助计算机来实现。而实际上,电话具有比计算机更高的普及率,如果允许人们通过电话来访问Internet的资源,那么这对于Internet的应用发展必将是一次质的飞跃。在这类应用前景的驱动下,VoiceXML 标准被提出来了,它是由World Wide Web Consortium (W3C)制定的。利用这种技术,用户可以通过电话按键或语音来访问Internet上的各种资源,它是语音浏览技术以及语音互联网的核心。与XML标准类似,VoiceXML是一种基于文本的语言,它只定义了数据的存取方式,用户必须编写程序,以便能解释、生成、传送VoiceXML文档。 VoiceXML为语音应用领域展现了一个广阔的未来,在语音门户、语音呼叫中心(Call Center) 、语音信息服务、语音电子商务等领域有着广泛的应用。而这些应用或服务可以很容易地和原有的数据系统结合起来,甚至可以轻易地从原有的各类应用中延展出来。使用VoiceXML的应用系统中,不要求用户学习复杂的高级语言,就可灵活扩充新业务。而无需再与开发商联系,重新定制开发,只需要编写几个 VoiceXML页面就可以实现新的业务流程。而且编制好的VoiceXML脚本可以随时随地加入到系统中,而不会影响系统的正常运行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

科技之歌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值