XML
  Home arrow XML arrow Page 7 - Sample Chapter: Early Adopter VoiceXML
Dev Articles Forums 
ADO.NET  
Apache  
ASP  
ASP.NET  
C#  
C++  
ColdFusion  
COM/COM+  
Delphi-Kylix  
Design Usability  
Development Cycles  
DHTML  
Embedded Tools  
Flash  
Graphic Design  
HTML  
IIS  
Interviews  
Java  
JavaScript  
MySQL  
Oracle  
Photoshop  
PHP  
Reviews  
Ruby-on-Rails  
SQL  
SQL Server  
Style Sheets  
VB.Net  
Visual Basic  
Web Authoring  
Web Services  
Web Standards  
XML  
Mobile Linux 
App Generation ROI 
IBM® developerWorks 
Sun Developer Network 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
XML

Sample Chapter: Early Adopter VoiceXML
By: Tim Pabst
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 5 stars5 stars5 stars5 stars5 stars / 1
    2002-09-04

    Table of Contents:
  • Sample Chapter: Early Adopter VoiceXML
  • VoiceXML With XSLT (HTML and WML)
  • System Architecture
  • System Architecture (contd.)
  • Generating MyRubberbandsML
  • Generating MyRubberbandsML (contd.)
  • Generating MyRubberbandsML (contd.)
  • Running the Stylesheet
  • Summary

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT


    Sample Chapter: Early Adopter VoiceXML - Generating MyRubberbandsML (contd.)


    (Page 7 of 9 )

    Just as we iterated over the order_history/order node-set to create grammars with options for all the orders of a customer, we must now iterate over these nodes again to create individual forms containing the details for each order. If there were consistently a very large number of orders per user, we might look at generating the order details on the fly using JSP or PHP to create a separate VoiceXML document.

    <xsl:for-each
    select="order_history/order">
    <xsl:variable name="order_detail_counter"
    select="position()"/>
    <form id="order_{$order_detail_counter}">


    The block above illustrates the other way XSLT offers for including dynamic content in an attribute value, this time through the <xsl:variable> element, the value of which can be output by preceding the identifier with the dollar sign, $. This technique is used several times when creating the VoiceXML forms for each order.

    <noinput>
    <!-- This falls through to order status top
    level -->
    <assign name="user_command"
    expr="'order status'"/>
    <goto next="#navigator"/>
    </noinput>

    <nomatch>
    <goto next="#errorHandler"/>
    </nomatch>

    <block>
    <assign name="form_pointer"
    expr="'order_{$order_detail_counter}'"/>
    </block>

    <field name="userSaid">


    The following code generates the prompt to announce the order detail:

    <prompt bargein="true"
    timeout="1s">
    This order was placed on <sayas
    class="date">
    <xsl:value-of
    select="order_date/@sayas"/></sayas>.
    <break
    msecs="500"/>
    The order consisted of
    <xsl:for-each select="product">
    quantity <xsl:value-of
    select="./@quantity"/> of product


    The <xsl:value-of> element below retrieves the name of the product with an XPath expression that selects products from the XML product_list section where the id attribute matches the id attribute of the current order. This is analogous to an SQL join between the customer_order and customer_order_product tables from relational schema. Note that XPath denotes an attribute with use of the at symbol, @.

    <xsl:value-of
    select="/myrubberbands/product_list/product[@id=current()/@id]"/>
    <break
    msecs="500"/>
    </xsl:for-each>
    The total of the order was


    Next, we see the VoiceXML <sayas> element put to use. Whether or not this causes the contents to be rendered correctly as currency depends on the TTS engine used, and its support for pronunciation markup. The rest of the block repeats the previous technique to add order options to the inline <grammar> element.

    <sayas
    class="currency">
    $<xsl:value-of
    select="total_charge"/></sayas>.
    The status of this order is
    <xsl:value-of
    select="order_status"/>.
    </prompt>

    <grammar
    type="application/x-jsgf">
    list |
    product list |
    more information |
    frequently asked questions |
    questions |
    order status |
    <xsl:for-each
    select="/myrubberbands/customer_record/order_history/order">
    order number
    <xsl:value-of select="position()"/> |
    </xsl:for-each>
    buy me
    </grammar>

    <filled>
    <assign
    name="form_pointer" expr="'productList'"/>
    <assign
    name="user_command" expr="userSaid"/>
    <goto
    next="#navigator"/>
    </filled>

    </field>
    </form>
    </xsl:for-each>


    At this point we'll skip over the product list option, because it doesn't illustrate anything we haven't already seen. However, the product listing prompt offers the user the option to say, "Buy me", in which case their call is transferred to the MyRubberbands.com's telephone service center by the placeOrder form below. This is the quickest way for the company to add some commerce capability to the voice system, but note that the VoiceXML <transfer> element is not implemented by all platforms. When the user returns from the call, they are unconditionally sent to the main menu by the subsequent <goto> element.

    <form id="placeOrder">
    <block>
    <prompt bargein="false"
    timeout="1s">
    Transferring your call to customer service.

    </prompt>
    </block>
    <transfer name="callSales"
    dest="MYRUBBERBND" connecttimeout="30s"
    bridge="true"/>
    <block>
    <goto next="#mainMenu"/>
    </block>
    </form>


    We can also skip over the frequently asked questions option, since it contains only static VoiceXML code. We are now almost at the end of our stylesheet, where the navigator form is located, holding the navigation logic for many of the state transitions in our interface design.

    It consists simply of an if-else construct that expresses the state transitions on the diagram of the user interface earlier. If more commands, states, or transitions were to be added to the design, the complexity of the interface might exceed the limitations of this method of implementation.

    <form id="navigator">
    <block>
    <if cond="user_command == 'product list' ||
    user_command == 'list'">
    <goto next="#productList"/>
    <elseif cond="user_command==
    'questions' ||
    user_command ==
    'frequently asked questions' ||
    user_command ==
    'more information'"/>
    <goto next="#FAQ"/>
    <elseif cond="user_command == 'order
    status'"/>
    <goto
    next="#orderStatus"/>
    <elseif cond="user_command == 'buy
    me'"/>
    <goto
    next="#placeOrder"/>


    The stylesheet drives the rest of the navigation engine by creating forms for each individual order in this customer's order history. It does this by means of the following <xsl:for-each> construct:

    <xsl:for-each
    select="order_history/order">
    <xsl:variable name="order_counter"
    select="position()"/>
    <elseif cond="user_command == 'order number
    {$order_counter}'"/>
    <goto
    next="#order_{$order_counter}"/>
    </xsl:for-each>
    <else/>
    <goto
    next="#mainMenu"/>
    </if>
    </block>
    </form>


    Finally, we come to the errorHandler form that is used by most of the <nomatch> handlers in the dialog. This error handler keeps a running count of the number of errors, and when four errors have occurred, it will apologize and disconnect the user. This isn't the friendliest way of handling errors, and is not suitable for a long-range solution that would more likely transfer the user to a human operator at this point. Not only that, but we'd probably want more sophisticated logic for processing errors, maybe using ECMAScript to vary the response according to the time elapsed since the last error.

    <form id="errorHandler">
    <block>
    <assign name="session_error_count"
    expr="session_error_count
    + 1"/>

    <if cond="session_error_count &lt;
    4">
    <prompt bargein="false"
    timeout="0.1s">
    I'm sorry, but I'm unable to
    understand you.
    </prompt>
    <if cond="session_error_count
    &gt; 2">
    <prompt
    bargein="false" timeout="0.1s">
    It seems I am having
    trouble.
    </prompt>

    </if>

    <goto
    next="#navigator"/>
    <else/>
    <prompt bargein="false"
    timeout="0.1s">
    I'm sorry, but I'm having a lot
    of difficulty understanding you. If you
    are currently in a noisy
    environment, please call back later.
    </prompt>
    <exit/>
    </if>
    </block>
    </form>


    All that needs to be done now is to close the document, after including an empty template matching standalone <product_list> elements, to suppress any output from them. Without this, default XSLT templates would be applied that output text children of any elements that aren't explicitly matched by a template already.

    </vxml>
    </xsl:template>
    <xsl:template match="product_list"/>
    </xsl:stylesheet>


    We've now reached the end of our VoiceXML stylesheet.

    More XML Articles
    More By Tim Pabst


     

    XML ARTICLES

    - Datatypes and More in RELAX NG
    - Providing Options in RELAX NG
    - An Introduction to RELAX NG
    - Path, Predicates, and XQuery
    - Using Predicates with XQuery
    - Navigating Input Documents Using Paths
    - XML Basics
    - Introduction to XPath
    - Simple Web Syndication with RSS 2.0
    - Java UI Design with an IDE
    - UI Design with Java and XML Toolkits
    - Displaying ADO Retrieved Data with XML Islan...
    - Widget Walkthrough
    - Introduction to Widgets
    - The Why and How of XML Data Islands






    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 5 hosted by Hostway
    Stay green...Green IT