Sample Chapter: Early Adopter VoiceXML - Generating MyRubberbandsML (contd.)
(Page 6 of 9 )
<form id="mainMenu">
<nomatch>
<goto next="#errorHandler"/>
</nomatch>
<noinput>
<goto next="#mainMenu"/>
</noinput>
<block>
<assign name="form_pointer"
expr="'mainMenu'"/>
</block>
<field name="userSaid">
<prompt bargein="true"
timeout="3s">
This is the main menu.
<break
msecs="500"/>
You can say product list to hear a list of
products.
<break msecs="500"/>
You can say order status to check your
order status.
<break
msecs="500"/>
You can say frequently asked questions to
get more
information.
<break
msecs="500"/>
You can always say main menu to return to
this
menu, or help for additional help.
</prompt>
<grammar
type="application/x-jsgf">
list
product list |
more information |
frequently asked questions |
questions |
order status
</grammar>In order to keep track of the currently active form, the global variable form_pointer is set. This could be used to implement specific navigation logic, for example, by changing the behavior of a command slightly depending on where the command originated. Once the prompt has been played, and the user has responded with an utterance matching the inline grammar, the <filled> handler for this <field> is entered. This copies the value returned by the grammar to the global variable user_command, which is used by the navigator form to direct control flow to the required form. We could also use <subdialog> and pass a parameter, but this is simpler, and sufficient for this application.
<filled>
<assign
name="user_command" expr="userSaid"/>
<goto
next="#navigator"/>
</filled>
</field>
</form>Now our main menu form is finished, we can start to implement the dialogs that provide the application's basic functionality. First up is the orderStatus form that makes the most extensive use of dynamic content generation:
<form id="orderStatus">
<noinput>
<assign name="user_command"
expr="'main menu'"/>
<goto next="#navigator"/>
</noinput>
<nomatch>
<goto next="#errorHandler"/>
</nomatch>
<field name="userSaid">We need a test here to check that the customer does indeed have outstanding orders, and play a message to that effect:
<prompt
bargein="true" timeout="1s">
<xsl:if
test="count(/myrubberbands/customer_record/order_history/order) !=
0">
This is a list of all your orders.
</xsl:if>
<xsl:if
test="count(/myrubberbands/customer_record/order_history/order) = 0">
You have not placed any orders within the
last thirty days.
</xsl:if>
<break
msecs="500"/>The next block creates a prompt for each order that was in the source XML document by using the XSLT element <xsl:for-each> to select XML elements that match the XPath in its attribute. The sayas attribute from the <order_date> element in our XML file is used here to provide an audio cue to identify the order to the user.
<xsl:for-each
select="order_history/order">
<sayas
class="date">
<xsl:value-of
select="order_date/@sayas"/>,
</sayas>
you placed an order. Say order number
<xsl:value-of
select="position()"/>
to hear more about it.
<break msecs="500"/>
</xsl:for-each>
</prompt>
<grammar
type="application/x-jsgf">
list |
product list |
more information |
frequently asked questions |
questions |
order status | The grammar also includes an option dynamically generated by the XSLT code. The user can say, "order number one" to access data on the first order in their list. This JSGF could be improved to accept shorter instructions, such as "order one", or even "one", but be aware that using "order number" followed by the number will help the ASR system correctly identify the user utterance, and will probably improve application performance in this situation.
In this chapter, all the grammars are inline, but XSLT could just as easily be used to create standalone external grammars in separate files, or to generate grammars in multiple formats (GSL, JSGF, XML) from a common data source, by the application of different stylesheets.
<xsl:for-each
select="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>Next: Generating MyRubberbandsML (contd.) >>
More XML Articles
More By Tim Pabst