注册 | 登录
收藏 | 帮助
热门文章
编辑推荐
相关文章  
使用Honeypots同计算机蠕虫病毒作
脚本图片类后门的完美使用方法
另类:用Ftype巧妙清除病毒
CPU使用频率100%一定是中毒了吗
我的黑色工具箱—几款黑客工具的
菜鸟入门常用的八种安全工具使用
使用Windows防火墙十大经典问题荟
安全至上 网吧使用电脑必看5点技
让隐私高枕无忧 放心使用公用计算
使用TCP/IP协议栈指纹进行远程操
您现在的位置: 顶尖设计 >> IT学院 >> 编程开发 >> XML >> 文章正文
使用Perl创建VoiceXML应用程序
作者:刘彦青  来源:http://www.computerworld.com.c  点击:  更新:2006-12-19
简介:
简介 VoiceXML是一种用来创建可以通过电话访问的内容的基于XML的编程语言,这样的内容不仅仅是具有互联网访问功能的移动电话可以访问,普通的电话也照样可以访问这些内容。HTML使用图形用户界面访问网站的内容,而VoiceXML则通过语音界面访问内容,其中的语音和拨号盘代替了传统的显示器、键盘和鼠标。对VoiceXML及其工作原理进行详细的介绍不在本文的范围之内,有关这方面的知识请参与相关资料。 一个简单的例子 为了说明通过电话访问现有的互联网内容是如何简单,我们将使用Perl建立一个简单的CGI脚本文件,获取一个包含CPAN最近上传内容的文件,然后将文件转换为VoiceXML,以便用户能够通过VoiceXML网关在电话上访问这些内容。 use strict; use XML::XPath; use LWP::UserAgent; 加载必要的模块后,在脚本程序的开始,我们创建新的HTTP::Request和 LWP::UserAgent对象,然后调用LWP::UserAgent的simple_request方法为RSS文件请求远程服务器。 my $news_url = 'http://search.cpan.org/recent.rdf'; my $request = HTTP::Request->new('GET', $news_url); my $ua = LWP::UserAgent->new(); my $response = $ua->simple_request($request); 发出请求后,我们将开始输出VoiceXML。首先创建vxml root元素和包含一个block元素的表格。在block元素中放入一个audio元素,告诉用户在RSS文件处理过程期间需要耐心地等待,然后用一个goto元素告诉VoiceXML浏览器跳到当前文档中标有headlines的小节。 print qq* <vxml>   <form id="greeting">     <block>       <audio> Please wait while I process the c pan news feed.       </audio>       <goto next="#headlines"/>     </block>   </form> *; 然后我们将对response对象进行测试,确保我们已经收到了远程的RSS文件。如果已经收到了远程文件,则创建一个新的XML::XPath实例,并将response对象的内容小节传送给它进行解析。如果在请求文件或在解析返回的内容时出现错误,则将出错的信息存储在$error中以供以后分析用。尽管封装对XML::XPath最初调用的eval块增加了一些系统开销,但在解析过程出现错误时,它能够使我们很“体面地”退出程序,如果没有它,解析出现错误将使脚本意外地结束。 my ($error, $xp); if ($response->is_success) { eval { $xp = XML::XPath->new(xml => $response->content); $xp->find('/'); }; $error = 'Error parsing RSS file ' . $@ if $@; } else { $error = 'Remote server returned ' . $response->message(); } 如果出现错误,脚本则会向用户返回一个描述错误的audio消息,挂断当前用户的连接,并关闭脚本。 if ( defined($error) ) { print qq*    <form id="headlines">      <block>        <audio> I'm sorry. The following error occurred while fetching the headlines file. $error Please try again later.        </audio>        <disconnect/>      </block>   </form> </vxml> *; } 如果RSS文件的获取和解析过程都没有出现错误,我们将创建一个新的form元素,然后,利用封装在block中的一个audio元素,通知用户解析已经成功,准备收听他所需要的信息。 else { print qq*   <form id="headlines">     <block>       <audio> The RSS file has been fetched and processed successfully. The following modules have recently been up loaded to c pan.       </audio>     </block>     <block> *; 然后,我们在一个循环中处理RSS文档中的所有item元素。对于每一个item元素我们都输出一个相应的audio元素,让VoiceXML文档使用每个item元素title子元素的值作为需要输出的文本内容。 foreach my $news_item ($xp->findnodes('//item')) { print "<audio>" . $news_item->findvalue('title') . "\n"; } 最后我们告知用户整个名单已经读完了,并欢迎他明天继续拨打,然后断开连接并关闭VoiceXML文档。 print qq*     <audio> This completes the latest c pan up loads. Please call again tomorrow.     </audio>     <disconnect/>     </block>   </form> </vxml> *; } 尽管这一段脚本并没有什么实际的用处,但可以考虑一下我们在这一段脚本中完成的任务。在短短的没有几行的脚本中,我们从远程的网站上取出了所需要的资源,并提取出我们关心的内容,并使这些信息可以从全世界的任一部电话上接听。 创建动态的VoiceXML应用 尽管上面的例子揭示出通过电话提供互联网网站内容和服务的可能性,但用户和VoiceXML应用之间的“对话”还太缺乏交互性。幸运的是,VoiceXML也提供了一些专门用来接收用户输入的元素。另外,象HTML表格那样,VoiceXML表格也可以用来接收通过标准的HTTP GET和POST方法向服务器传送的数据。 在下面的例子中,通过创建一个很小的讲述“神奇的oracle”故事的应用程序,我们根据使用POST方法输入的数据创建了一个动态的VoiceXML文档。为了使程序简单明了,我们将把程序分为二部分:一个纯文本的包含获取用户输入表格的VoiceXML文档和动态的、由CGI创建的对这些问题的回答进行规格化的文档。 首先,我们来创建这个表格。在表格的开始处是一个问候语,只有用户在第一次连接时才会听到它。 <vxml>   <form id="greeting">     <block>       <audio> Thank you for calling the mystic oracle!       </audio>       <goto next="#main_query"/>     </block>   </form> 然后,我们将开始设计主表格。这个表格只包含一个名字为query_type的字段,它的用途是获取用户的问题。我们需要特别注意grammar元素,它使VoiceXML应用开发人员能够精确地确定给定字段能够接收什么类型的输入。例如,在我们的例子中,如果用户的问题中含有“career”、“job”、“boss”、“coworker”或“department”等词汇,query_type字段的值勤将被设置为“career”。   <form id="main_query">       <field name="query_type"> } [career job boss coworker department] {} [family husband wife mother father son daughter] {} ] ]]>       </grammar> prompt元素通知VoiceXML网关向用户朗读一段文字,并等待响应。在本例中,如果用户提问的问题中包含上面一段脚本中的grammar元素中定义的词汇之一,应用程序就会向用户表示感谢,并使用POST方法把信息提交给应用程序的CGI部分。submit元素的namelist属性允许我们指定准备提交当前文档中的哪个字段或变量。       <prompt> Clear your mind and concentrate on your question. You may ask your question now.       </prompt>       <filled>         <audio>thank you.</audio>         <submit next="http://mysite.tld/cgi-bin/mystic_response.cgi" method="POST" namelist="query_type"/>       </filled> 下面的代码是一个错误陷阱结构,可以使oracle应用有一个更合理的界面。如果用户所问的问题中不包含上面的grammar元素中所包含的词汇,nomatch标记中所包含的文本就会被朗读出来。reprompt元素使VoiceXML浏览器返回到所在模块的开始,并重新朗读前面的提示。如果用户没有提问问题,系统将根据每个noinput的count属性定义的顺序每次朗读一个noinput元素。如果三次提示后用户仍然没有提问问题,应用程序将挂断与用户的连接。       <nomatch> The mystic oracle can only answer questions about romance, career, or family matters. Please try again.         <reprompt/>       </nomatch>       <noinput count="1"> I can sense your apprehension.         <reprompt/>       </noinput>       <noinput count="2"> You must say something.         <reprompt/>       </noinput>       <noinput count="3"> Please call back when you are less stressed.         <disconnect/>       </noinput> 下面的内容是为了结束query_type字段、其父表格和最顶部的vxml元素。     </field>   </form> </vxml> 下面我们来创建响应用户问题的CGI脚本程序。这一脚本程序将接收一个通过POST方法传送、名字为query_type的字段的参数,query_type的可能的值为romance、career或 family。 use strict; use CGI qw(:standard); my $q = CGI->new(); my $query_type = $q->param('query_type'); 首先,我们将生成一个针对用户所提问题的比较含糊的答案。 my @intro_phrases = ('My sources say', 'All signs indicate that', 'Search your heart. You know');

[1] [2] 下一页






  • 上一篇文章:
  • 下一篇文章:
  • 分享此文:该页面添加到 Mister Wong 添加到雅虎Yahoo!收藏 Add to:Del.icio.us Post to Furl Digg this 添加到Google书签 reddit spurl blogmarks 365Key 评论  收藏  分享  打印
     我来说两句
    姓名:       验证码:   
    主页: 
    评分: 1分 2分 3分 4分 5分
    本频道近期热评文章:
      关于我们 | 联系我们 | 站点地图 | 广告投放 | 友情链接 | 在线留言 | 版权申明
    版权所有 © 2004-2007 顶尖设计(bobd.cn)
    未经授权禁止转载,摘编,复制本站内容或建立镜像. 沪ICP备07504942号 
    网络110
    报警服务