VoiceXML 2.1 Development Guide Home  |  Frameset Home

  tutorial Call Flow   |  TOC  |  tutorial Using Audio Files  

Tutorial: Document Navigation

This tutorial is based on the things you accomplished in previous Lessons. If you have not completed those tutorials, you'll need to go through them first, little buddy.

Step 1: creating our initial VoiceXML structure


From our previous Lesson, we now recognize the following structure as a normal starting point:

<?xml version="1.0" encoding="UTF-8"?>
<vxml version = "2.1">

</vxml>



Step 2: our first look at variables

As with any XML implimentation, there must be a way to create variables to contain dynamic pieces of information. VoiceXML is no exception, and the method for creating variables is very straightforward:


  <var name="MyFavoriteActor"  expr=" 'Tony Danza' "/>
  <var name="MyFavoriteTVShow" expr=" 'Who\'s the boss' "/>
  <var name="TonysSATScore"    expr="1600"/>


So here we have three variables, each with an assigned value. Couple of things to note -- the first is that the value inside the "expr" attribute is contained in single quotes. Why is this? The single quotes tell VoiceXML that we are creating a string variable and not a numeric variable. If the single quotes were not there, it would assume that we were trying to reference another variable (thus, expr="Bob" will attempt to get the value of a variable named "Bob" NOT assign the value "Bob" to a variable -- to assign the value, it must be expr="'Bob'"). The single quotes are not included in the variable, so "'Tony Danza'" becomes simply "Tony Danza". Notice that our variable named "TonysSATScore" does not need single quotes -- it is a numeric variable and does not run the risk of being confused by VoiceXML as a variable name because variables cannot have numeric names (i.e., you can call a variable "One" but not "1"). Another point of merit is that we have to use an "escape" character if we actually want to have an apostrophe included in our variable's value. You do this by scripting "\'" instead of just a single quote. That backslash is not a typo. Lastly, variables beginning with the underscore character ("_") are reserved by VoiceXML for internal use, so you most certainly won't see any of that sort of foolishness here, hombre.

Variables can be created inside a VoiceXML structure such as a <form> and <block> layout, but we are going to put them in the "application root". This is a fancy way of saying that we want variables that are scoped outside of a specific form, which can then be accessed later in another part of the application (in this case, in another file altogether).


Step 3: transferring to a new page or URL

While variables can obviously be used in the same page, more often variables are created so that a specific value can be carried from one application or file to another. In our last tutorial, we learned how to use the <goto> element to hop around inside a file, but remember, that tag can also navigate to a new URL/file as well:

  <goto next="callflowB2.xml"/>

The "next" attribute tells VoiceXML the URL to load. This destination can be relative (such as our example above), or it can be fully qualified (such as: http://www.myserver.com/helloworld/callflowB1.xml).

Let's finish this file, and save it as 'callflowB1.xml':

<?xml version="1.0" encoding="UTF-8"?>
<vxml version = "2.1">

<meta name="maintainer" content="YOUREMAILADDRESS@HERE.com"/>

  <var name="MyFavoriteActor"  expr="'Tony Danza'"/>
  <var name="MyFavoriteTVShow" expr="'Who\'s the boss'"/>
  <var name="TonysSATScore"    expr="1600"/>
 
  <form>
    <block>
      <goto next="callflowB2.xml"/>
    </block>
  </form>
</vxml>


Instead of doing a menu with voice recognition and call flow (as one would normally do), we are simply creating variables, transferring to a new page, and then using text-to-speech to read the values of those variables. Since our application is so simple, our second file will be as basic as the first file, and it might look like this:

<?xml version="1.0" encoding="UTF-8"?>
<vxml version = "2.1" application="callflowB1.xml">

<meta name="maintainer" content="YOUREMAILADDRESS@HERE.com"/>

  <form>
    <block>
      Hello World.
      My favorite actor is <value expr="application.MyFavoriteActor"/>
      and my favorite TV show is <value expr="application.MyFavoriteTVShow"/>
      Tony's SAT score was <value expr="application.TonysSATScore"/>
    </block>
  </form>
</vxml>


Here we see that to retrieve the value of a specific variable, we use the <value> element. Notice that we have introduced a new attribute called "application" to our <vxml> tag. This tells the VoiceXML interpreter that the file/URL inside the quotes is the main application document. What does this do for us? Among other things, it allows us to share and access the variables correctly. Since we are using application level variables in our second file, we cannot reference them with simply their names; instead, we have to use an "application." prefix in front of the variable names. Otherwise, everything here looks familiar to us now.

Note: These are just some of finer points of variable creation. For a more exhaustive look at VoiceXML's standard implimentation of variables, scopes, declarations, etc., please have a look at our variable reference appendices. Go ahead and save this file as "callflowB2.xml", as our mini-application is now complete.


Step 4: upload, and try it out

All that remains now is to upload your new hello world VoiceXML application; you can use your own webserver for hosting the application, or you can use our Voxeo File Manager to upload the app to our free hosting servers.

Now you can use the Voxeo Account Manager to provision a number to your call flow application, and  then call the associated number to hear the results.

Download the Code!

  Motorola source code

What we covered






  ANNOTATIONS: EXISTING POSTS
eosmann
10/26/2004 3:44 PM (EDT)
Please note that the code sample shown should read:
<vxml version = "2.1" application="callflowB1.xml" >
Closing bracket missing!
MattHenry
10/26/2004 3:59 PM (EDT)
Wow, good catch. I'll see that this is corrected; thanks again for bringing this to my attention.

~Matt
Midnight_Raven
12/7/2004 3:14 AM (EST)
Comment deleted due to stupidity on my part...
martpotters
2/17/2005 5:50 PM (EST)
in declaring the variables, can we name them different so we can reference the names directly.  for example
  <var name="MyFavoriteActor"  expr="'Tony Danza'"/>
  <var name="MyFavoriteTVShow" expr="'Who\'s the boss'"/>

can we say:
  <var name1="MyFavoriteActor"  expr="'Tony Danza'"/>
  <var name2="MyFavoriteTVShow" expr="'Who\'s the boss'"/>

so we can call name1 or name2 without reference to "MyFavoriteActor" or "MyFavoriteTVShow", respectively, in another page. e.g
      My favorite actor is <value expr="application.name1"/>
      and my favorite TV show is <value 
      expr="application.name2"/>

will the above expression work.

thanks
mart
     
steve.sax
2/17/2005 6:08 PM (EST)
Hello Mart,

I don't think your syntax below is valid, as the attribute 'name1' will immediately throw a parse error to the browser. If I am missing the point of your question, it might help to get a full blown-test case up, and send in debugger output that illustrates the exact nature of your request, so that there isn't any confusion.

Regards,

Steve
martpotters
2/17/2005 6:36 PM (EST)
thanks i what you said clarifies it now i know "name" is actually an attribute and not a variable in itself like i earlier thought.
thanks i'm good now
Khamyl
5/9/2006 4:49 PM (EDT)
Hi,

What is exactly the <meta> tag good for in this example?

thx
MattHenry
5/9/2006 5:04 PM (EDT)
Hello Khamyl,

This is covered in exquisite detail at the following links:

http://www.voicexmlguide.com/motty_meta.htm
http://www.voicexmlguide.com/meta.htm

Regards,

~Matt
sramanna
6/9/2006 5:52 PM (EDT)
How do I get the single quotes around the string when I am assigning it to a jsp variable.

<% String x1= "Y";
%>

and when I do this,
<var name ="y1" expr = "<%=x1%>" />

It doesnt work, how do I fix this.
Michael.Book
6/10/2006 12:28 AM (EDT)
Howdy sramanna,

I believe JSP simply uses the backslash to escape special/reserved characters such as single quotes.  For example:
_____________________

<% String foo = "Bob\'s bar"; %>
_____________________


Now, it just so happens that ECMA Script expressions in VoiceXML use the same escape character for single quotes:
_____________________

<var name ="foo" expr="'Bob\'s bar'"/>
_____________________

If you were going to dynamically insert the value of your JSP var into a VoiceXML expression, it might look like so:
_____________________

<% String foo = "Bob\'s bar"; %>
<var name ="foo" expr="'<%=foo%>'"/>
_____________________


I hope this helps...


Have Fun,

~ Michael
jason.m.hanna
2/15/2007 10:09 AM (EST)
Hi, perhaps I'm leaping ahead here, but it seems one purpose of breaking apart your forms into separate xml files would be to create reusable elements that could be called from several different entry points.

Is there another way to reference these globally scoped variables without identifying the caller in the "application" attribute?

I could certainly do this if my second XML file was generated by ASP/JSP/etc., but it doesn't seem very elegant. Then again, globally scoped variables are not all that elegant a programming technique, either...

Thanks,
-jmh
mikethompson
2/15/2007 11:59 AM (EST)
Hi there,

If you wish to maintain variable values across multiple documents in VoiceXML, you have two options.

1.  Declare an application root document to store your global variables
2.  Pass variable information over to your other documents via the <submit> element with a namelist.

For example:

<submit next="LeafDocument2.xml" namelist="Var1 Var2 MyVar9"/>

This will require the use of server-side, as will most extensive applications.

Best,
Mike Thompson
Voxeo Corporation
esirkin
5/2/2007 5:27 AM (EDT)
Mike:

I am "stubbing out" my documents so I can test before integration with the server side code.  So I am very interested in using <submit> to transfer control to a second document and using namelist to transfer information to the second document.  So my questions relate to how this would work.  Using the example you provide,

Doc1.vxml
<?xml version="1.0" encoding="UTF-8"?>
<vxml version = "2.1">

<var name="Var1" expr="'good'"/>
<var name="Var2" expr="'bad'"/>
<var name="MyVar9" expr="'ugly'"/>

<submit next="Doc2.vxml" namelist="Var1 Var2 MyVar9"/>

<exit/>
<vxml/>
=======================================
Doc2.vxml
<?xml version="1.0" encoding="UTF-8"?>
<vxml version = "2.1">

<!--
Q1:  Are these var declarations redundant, needed or going to cause an error?
-->
<var name="Var1"/>
<var name="Var2"/>
<var name="MyVar9"/>

<prompt>
  You are <value expr="Var1"/> and not <value expr="Var2"/>
  <prompt/>

<log expr="'*****' + Var1 + '******'" label="trace:?level=VD_INFO"/>

<!--
Q2:  If I change a value for a var and then transfer control to a third document, will var take on the new value?
-->
<assign name="Var1" expr="'great'"/>
<submit next="Doc3.vxml" namelist="Var1 Var2 MyVar9"/>

<exit/>
<vxml/>
========================================

I realize that I can probably do this using root and leaf documents.  But trying to understand if what I propose will work as well.

Q3:
If I must use root/leaf, if the value for one of the root vars changes value in the leaf, does it also change at root so the value is carried into a second leaf document?

Thanks,

e
MattHenry
5/2/2007 1:55 PM (EDT)


Hi Eric,

In terms of passing data via <submit>, I should mention that you will need to employ some dynamic coding action to get at the values, as indicated in the below link:

http://docs.voxeo.com/voicexml/2.0/qs_vars.htm

As such, the first two questions that you pose here are not really relevant, unless I am misunderstanding you. To be clear, if we submit values to a static VXML document, the target isn't going to be able to access the variables declared in the submitting document while working in a purely static context. If you need to work in a static context, then using application-scoped variables via root/leaf is required.

To answer the last question the answer is a resounding "yes".

Hope this clarifies things for you,

~Matthew Henry
dshrout
8/9/2007 1:50 PM (EDT)
In your example, you are only using initialized values. When I try to modify the value of a variable in the Root document, that value gets reset when I transfer control to a Leaf document.

The code below is exactly what I used to test on Voxeo's Developer Network.

Is there something I'm missing?

=================================================================
=== RootDoc.vxml

<?xml version="1.0" encoding="UTF-8"?>
<vxml version = "2.1">

  <var name="TestVar" expr="'Initialized'"/>

  <form>
    <block>
      <log>TestVar = <value expr="TestVar" /></log>
      <assign name="TestVar" expr="'Modified'" />
      <goto next="LeafDoc.vxml"/>
    </block>
  </form>
</vxml>


=================================================================
=== LeafDoc.vxml

<?xml version="1.0" encoding="UTF-8"?>
<vxml version = "2.1" application="RootDoc.vxml">

  <form>
    <block>
    <log>TestVar should equal "Modified"</log>
    <log>TestVar = <value expr="application.TestVar" /></log>
    </block>
  </form>
</vxml>


mikethompson
8/9/2007 4:12 PM (EDT)
Hi there,

It's generally a best practice to *not* use executable content in your application root document.  Is there any reason you are not modifying the value from within the first leaf?  This would be the preferred method.  For exmaple:

=================================================================
=== RootDoc.vxml

<?xml version="1.0" encoding="UTF-8"?>
<vxml version = "2.1">

  <var name="TestVar" expr="'Initialized'"/>

</vxml>


=================================================================
=== LeafDoc.vxml

<?xml version="1.0" encoding="UTF-8"?>
<vxml version = "2.1" application="RootDoc.vxml">

  <form>
    <block>
    <log>TestVar should be set to initialized</log>
   
    <assign name="application.TestVar" expr="'Modified'"/>

    <log expr="'**********TestVar is now:' + application.TestVar + '********'"/>

    </block>
  </form>
</vxml>

With the above code, all you have to do differently is map the startURL to leafDoc.vmxl, as the application root document will automatically be preloaded (since you have the application attribute in your VXML element).  There is really no need to ever hit a root document first, and manually code a <goto>.

Hope this helps,
Mike Thompson
Voxeo Corporation
dshrout
8/9/2007 5:34 PM (EDT)
I am new to VoiceXML and was just following examples given. In this sites documentation and in a couple different books I have, multidocument applications start with the root doc and <goto> the leaf doc.

I had actually recoded to use your suggestion, sort of. I put all my var declarations and javascript includes in a new root doc but I was still starting with the root and using a <goto> to get to the first leaf. I didn't realize I could just start with the leaf.

Thank you for your help. I really do appreciate it.
-Don
borisattva
9/14/2007 9:17 AM (EDT)
if there are multiple documents with desired variables, can they all be listed?

ex:

<vxml version = "2.1" application="callflowB1.xml" application1="callflowC1.xml">

and then their variables be referenced as
application.VariableA
application1.variableB

etc and so on
MattHenry
9/14/2007 11:46 AM (EDT)


Hi there,

Assuming that I understand the question, then the answer is 'yes': so long as any leaft documents reference the application root document then an app variable that is declared in 'leaf1.xml' will be accessible within 'leaf2.xml'.

Does this answer your question?

~Matthew Henry

login

  tutorial Call Flow   |  TOC  |  tutorial Using Audio Files  

© 2003-2008 Voxeo Corporation  |  Voxeo IVR  |  VoiceXML & CCXML IVR Developer Site