VoiceXML 2.1 Development GuideHome  |  Frameset Home


<foreach>  element

The VoiceXML 2.1 specification introduces the new <foreach> element, which allows the developer an inherent browser method for looping through items in an array, and outputting them via TTS, or via <audio>. This element must specify both the 'array', as well as the 'item' attributes, else an error.semantic will be thrown.


usage
<foreach array="(ECMAScript Expression)" item="NMTOKEN">


attributes
arrayData Type: (ECMAScript Expression)Default: Required
The 'array' attribute defines the name of the array referenced by the <foreach> element,; failure to specify this attribute will result in an error.semantic event being thrown.
itemData Type: NMTOKENDefault: Required
The 'item' attribute denotes the name of the variable that stores a particular array value as it is being iterated within the loop. If this variable is not already defined, then it will be declared upon invocation of the <foreach> element.



shadow variables
none


parents
<block> <catch> <error> <filled> <foreach> <help> <if> <noinput> <nomatch> <prompt>


children
<assign> <audio> <break> <clear> <data> <disconnect> <enumerate> <exit> <foreach> <goto> <if> <log> <mark> <prompt> <reprompt> <return> <script> <submit> <throw> <value> <var>


code samples
<Foreach array-item> sample
<?xml version="1.0" encoding="UTF-8"?>
<vxml version = "2.1">

<meta name="author" content="Matthew Henry"/>
<meta name="copyright" content="2005 voxeo corporation"/>
<meta name="maintainer" content="YOUR_EMAIL@HERE.COM"/>

  <form id="F1">
      <block>

      <prompt>
        welcome to the gaming news phone network.
      </prompt>

      <script>
        var arrayGames =
["duke nukem forever", "half life 2", "doom 3",
"shadow warrior 2", "track and field: grecian edition" ];
      </script>
       


        <prompt>
          The most anticipated games for this year are
          <break/>
        </prompt>

       
        <foreach item="games" array="arrayGames">
            <prompt><value expr="games"/><break/></prompt>
        </foreach>

            <prompt>
But of course, we all know that Duke Nukem Forever is
never, ever, ever, going to be released, so gamers may
                  as well pin their hopes on Miss Pac Man 3, or Command
                  and Conquer: French Assault.</prompt>
      </block>
  </form>
</vxml>



additional links
W3C 2.1 Specification


  ANNOTATIONS: EXISTING POSTS
mkoe
7/4/2006 1:20 PM (EDT)
Hi,

How can I use <subdialog> in a <foreach>?  It seems the vxml doesn't allow to execute subdialog within <foreach>.  I put my sample as the following.  Thanks for your help.

<form name="main">
<foreach item = "theCurrentSAVAccout" array = "SAVAccoutList">
<subdialog name="result" src="#SayAccountInformation">
<param name="currentMonth" expr="theCurrentSAVAccout.currentMonth" />
<param name="previousYear" expr="theCurrentSAVAccout.previousYear" />
<param name="isJanToMay" expr="theCurrentSAVAccout.isJanToMay" />
<filled />
</subdialog>
</foreach>
</form>

<form name="theCurrentSAVAccout">
<block>
</block>
</form>

When I run the above code in IBM VoiceToolkit, I am getting error

---------------------------------------------------------
INFO: Call is connected.
ERROR - Cause: VXML Document error:

and form the system error log.


[7/4/06 11:20:21:250 EDT] 254cc570 VXML          E  3006509539553984@127.0.0.1 TRAS0014I: The following exception was logged com.ibm.voice.server.vc.VContainerException: VContainer::dialogRun
at com.ibm.voice.server.vc.core.VContainer.dialogRun(VContainer.java:389)
at com.ibm.voice.server.vxp.VXPRuntime$RunWorker.runWork(VXPRuntime.java:747)
at com.ibm.voice.server.vxp.VXPWorker.run(VXPWorker.java:84)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:912)
Caused by: com.ibm.vxi.intp.BrowserProcException: VXIContext::interpret:
at com.ibm.vxi.intp.VXIContext.interpret(VXIContext.java:512)
at com.ibm.vxi.intp.VoiceBrowser.run(VoiceBrowser.java:570)
at com.ibm.voice.server.vc.core.VContainer.dialogRun(VContainer.java:383)
... 3 more
Caused by: error.badfetch:com.ibm.vxi.intp.CatchEvent: file:/C:/myViews/snapshots/MKOE_VoiceXML/vxml/ITSWebProject/WebContent/main/vxml/interestEarned.vxml:VXML Document error:
Line  : 353
Column: 18
URI  : null

<SNIP>

MattHenry
7/4/2006 2:51 PM (EDT)


Hello there,

I think that there is a bit of confusion that I should clear up. Checking the parent-child listing for theelements in question, <subdialog> is not a valid child of <foreach>, so this is not a valid option. You could however, code a foreach loop on the serverside, and output your subdialogs as needed.

~Matt
dragondad
9/15/2006 12:02 PM (EDT)
  Can I use the <foreach> recursively to support two dimensional array assignment.
  For example:

  <foreach item="games" array="arrayGames">
          <prompt><value expr="games"/><break/></prompt>
          <foreach item="scores" array="arrayScores">
              <prompt><value expr="scores"/><break/></prompt>
          </foreach>
  </foreach>

  this looks like a valid script, but will the result as expected.
MattHenry
9/15/2006 2:20 PM (EDT)


Hi there,

I haven't tested this personally, but I see no reason why this wouldn't work. If you want to give me a sample array that is specific to this topic, I can run a test and find out, though...let me know.

~Matt
shawnaslam1
4/16/2008 7:06 AM (EDT)
My question is once we have assigned the array string to the VXML array now can we access the specific index of the VXML array as we can do in any language or in JSP.
It seems to me that when we use array in foreach loop it plays the array and didn't give us any control

so is there any way in we each we can access the specific index of the array.
your spontaneous action will be great for me.


Regards,
Shawn Aslam
MattHenry
4/16/2008 2:48 PM (EDT)


Hi Shawn,

What you are looking to do in this case exceeds what the <foreach> element was designed to do. If you want finer-grained control over accessing individual index positions and their associated values, then you would likely be better off doing this by crafting an ECMAScript function to achieve this goal.

Hope this helps,

~Matthew Henry
Vijeth
9/2/2008 7:04 AM (EDT)
Hello Matt,
  I am trying to what is the value of each element of an array. But i'm not getting how to?? Following is my code

<vxml xmlns="http://www.w3.org/2001/vxml" xml:lang="en-IN" 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" version="2.0">


<form id="recharge">
<script>
        <![CDATA[
          function say(number){
            var dig= new Array();
            for(var i=0; i<number.length; i++)
              dig[i]=number.charAt(i);
            return dig;
          }
         
         
        ]]>
    </script>

  <field name="select" type="digits" >

  <prompt>
      please enter the recharge code followed by #
  </prompt>
 
  <nomatch>
    <prompt>
    nomatch
    </prompt>
    <reprompt/>
  </nomatch>   
  <noinput>
      <prompt> call you later</prompt><reprompt/>
  </noinput>
 
  <filled>
    <var name="x" expr="say(select)"/>
    <foreach array="x" item="xx">
        <if cond="x==1">
          <prompt>one</prompt>
        <else/>
          <prompt>other</prompt>
        </if>
    </foreach>
  </filled>

</field>
</form>
</vxml>

I want "one" prompt should be played when i'd pressed 1#.
Please help me out.

voxeoJeffK
9/2/2008 7:30 AM (EDT)
Hi,

Your <foreach> code looks fine for the most part. I would recommend single quoting the conditionals so that they are tested as a string like so: <if cond="x=='1'">. I added a few more iterations to test your code, and it seems to work just fine:


  <filled>
    <var name="x" expr="say(select)"/>
    <foreach array="x" item="xx">
        <if cond="x=='1'">
          <prompt>you chose one</prompt>
        <elseif cond="x=='2'"/>
          <prompt>you chose two</prompt>
        <elseif cond="x=='3'"/>
          <prompt>you chose three</prompt>
        <else/>
          <prompt>you chose other</prompt>
        </if>
    </foreach>
  </filled>

Regards,
Jeff K.
Vijeth
9/2/2008 8:01 AM (EDT)
Thank you Jeff, It worked.
mtatum111
9/24/2008 12:23 PM (EDT)
I am a little confused here.  Just not sure when to use CDATA and not to use CDATA

We have   
<script>
var arrayGames =
["duke nukem forever", "half life 2", "doom 3",
"shadow warrior 2", "track and field: grecian edition" ];
      </script>
       

why wouldn't we have the following instead

<script>
<![CDATA[
var arrayGames =
["duke nukem forever", "half life 2", "doom 3",
"shadow warrior 2", "track and field: grecian edition" ]; ]]>
      </script>
VoxeoDustin
9/24/2008 12:32 PM (EDT)
Hey Melissa,

CDATA is only necessary to escape characters normally reserved in XML, such as <, >, &. In the code you pasted, it is not necessary as there are no reserved characters in use that might cause an XML parse error.

Thanks,
Dustin

login



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