VoiceXML 2.1 Development GuideHome  |  Frameset Home

  Downloadable GSL Subgrammar Library  |  TOC  |  J: grXML Grammars  

Multislot Subgrammars

If we want to get really tricky, we can also construct a subgrammar that returns multiple slot values. This simply requires us to return the array of slot values in all subgrammar return values, as illustrated below:

gslMultiSlotSub.gsl


MYRULE  [

(COLOR:a ?MAKE:b ?MODEL:c)
  {
<color_literal $a.literal>  <color_item_code $a.item_code>
<make_literal $b.literal>  <make_item_code $b.item_code>
<model_literal $c.literal>  <model_item_code $c.item_code>
    }
]

COLOR [
(red)    {return ([<literal "red">    <item_code "R1">]) }
(blue)  {return ([<literal "blue">    <item_code "G1">]) }
(green)  {return ([<literal "green">  <item_code "B1">]) }
]

MAKE [
(chevy)  {return ([<literal "chevy">  <item_code "CH2">  ])}
(ford)    {return ([<literal "ford">    <item_code "FD2">  ])}
(toyota)  {return ([<literal "toyota">  <item_code "TY2">  ])}
]

MODEL [
(sedan) {return ([<literal "sedan"> <item_code "SED3">])}
(truck) {return ([<literal "truck"> <item_code "TR3">])}
(battle ship) {return ([<literal "battleship"> <item_code "BS3">])}
]


gslMultiSlotSub.xml


<?xml version="1.0" encoding="UTF-8" ?>
<vxml version="2.0">
  <meta name="maintainer" content ="your_email_address@example.com"/>


<form id="MyForm">
      <field name="MyField">
        <grammar src="gslMultiSlotSub.gsl#MYRULE" type="text/gsl"/>
       
        <prompt>
          give me a color, a make, and a model to order your new vehicle. 
        </prompt>

        <nomatch>
          <prompt>
            I need a color, make, and model of the vehicle you would like to order, such as
            <break/>
            Red, Chevy, Truck.
          </prompt>
        </nomatch>

        <filled>
          <prompt>
            You said you wanted a

                    <value expr="lastresult$.interpretation.color_literal"/>
                    <value expr="lastresult$.interpretation.make_literal"/>
                    <value expr="lastresult$.interpretation.model_literal"/>
              <break/>
   
            Part numbers

              <value expr="lastresult$.interpretation.color_item_code"/>
              <break/>

              <value expr="lastresult$.interpretation.make_item_code"/>
              <break/>

            and
              <value expr="lastresult$.interpretation.model_item_code"/>

            have been ordered, and will be shipped to you shortly.
          </prompt>
        </filled>
      </field>
  </form>
</vxml>


Using NBest with a Multislot subgrammar


From one of our premier voiceweb developers comes the following code sample, demonstrating how one can integrate a multislot subgrammar's return arrays with some Nbest post-processing. This can come in very useful in applications where similar sounding utterances return multiple slots to the application. Yet another fine example of ingenuity at it's finest.


<?xml version="1.0"?>

<vxml version="2.0">
<meta name="author" content="Ganz Chockalingham"/>

<var name="resultLen"/>
<var name="resultArray"/>
<var name="hwyname" />
<var name="hwyid" />
<var name="hwynameArray" />
<var name="hwyidArray" />



<form id="form1">
<field name="hwy" slot="hwy">
<audio>what highway would you like to take?</audio>
<property name="maxnbest" value="5"/>
<grammar src="HIGHWAYS.gsl#SDHIGHWAYS" type="text/gsl">
<nbest xml:space="preserve">
<![CDATA[
for( var i = 0; i < lastresult$.length; i++ )
{
var number = lastresult$[i].interpretation.number;
if( number != undefined && skiplist[number] == undefined )
return lastresult$[i];
}

lastresult$[0].alternate = true;
return lastresult$[0];
]]>
</nbest>
</grammar>
<catch event="nomatch noinput SPEECH_TOO_EARLY">
<audio>Sorry I did not understand.</audio>
<goto next="#ask1" />
</catch>

<filled>

<assign name="resultArray" expr="application.lastResult$"/>
<assign name="resultLen" expr="resultArray.length"/>
<log expr="'resultLen = ' + resultLen"/>
<log expr="'hwy$[0].interpretation.hwyname = ' + hwy$[0].interpretation.hwyname"/>


<if cond="resultLen == 5">

<assign name="hwynameArray" expr="[hwy$[0].interpretation.hwyname, hwy$[1].interpretation.hwyname,

hwy$[2].interpretation.hwyname, hwy$[3].interpretation.hwyname, hwy$[4].interpretation.hwyname]"/>
<assign name="hwyidArray" expr="[hwy$[0].interpretation.hwyid, hwy$[1].interpretation.hwyid,

hwy$[2].interpretation.hwyid, hwy$[3].interpretation.hwyid, hwy$[4].interpretation.hwyid]"/>

<elseif cond="resultLen == 4"/>
<assign name="hwynameArray" expr="[hwy$[0].interpretation.hwyname, hwy$[1].interpretation.hwyname,

hwy$[2].interpretation.hwyname, hwy$[3].interpretation.hwyname]"/>
<assign name="hwyidArray" expr="[hwy$[0].interpretation.hwyid, hwy$[1].interpretation.hwyid,

hwy$[2].interpretation.hwyid, hwy$[3].interpretation.hwyid]"/>

<elseif cond="resultLen == 3"/>
<assign name="hwynameArray" expr="[hwy$[0].interpretation.hwyname, hwy$[1].interpretation.hwyname,

hwy$[2].interpretation.hwyname]"/>
<assign name="hwyidArray" expr="[hwy$[0].interpretation.hwyid, hwy$[1].interpretation.hwyid,

hwy$[2].interpretation.hwyid]"/>

<elseif cond="resultLen == 2"/>
<assign name="hwynameArray" expr="[hwy$[0].interpretation.hwyname, hwy$[1].interpretation.hwyname]"/>
<assign name="hwyidArray" expr="[hwy$[0].interpretation.hwyid, hwy$[1].interpretation.hwyid]"/>

<elseif cond="resultLen == 1"/>
<assign name="hwynameArray" expr="[hwy$[0].interpretation.hwyname]"/>
<assign name="hwyidArray" expr="[hwy$[0].interpretation.hwyid]"/>
<assign name="hwyname" expr="hwy$[0].interpretation.hwyname"/>
<assign name="hwyid" expr="hwy$[0].interpretation.hwyid"/>
<goto next="#End"/>
<else/>

</if>

<goto nextitem="Bool_0"/>

</filled>

</field>

<block name="B_1">
<script>
<![CDATA[

function deleteElement(array, n) {
var length = array.length;
if (n >= length || n<0)                 
return;

for (var i=n; i<length-1; i++)     
array[i] = array[i+1];             

array.length--;

}
 
deleteElement(hwynameArray, 0);
deleteElement(hwyidArray, 0);


]]>

</script>
</block>


<field name="Bool_0" type="boolean">
<prompt>did you say, <value expr="hwynameArray[0]"/> ? </prompt>

<filled>



<if cond="Bool_0==true">
<assign name="hwyname" expr="hwy$[0].interpretation.hwyname"/>
<assign name="hwyid" expr="hwy$[0].interpretation.hwyid"/>
<log expr="'HYWID ==================================== : ' + hwyid"/>
<goto next="#End"/>
<elseif cond ="hwynameArray.length == 1"/>
<clear namelist ="Bool_0 hwy"/>
<prompt> i am having trouble. lets start over, shall we?</prompt>
<goto next="#ask1"/>
<else/>
<clear namelist="Bool_0"/>
<goto nextitem="B_1"/>
</if>
</filled>
</field>
</form>


<form id="End">
    <block name="block10">
      <prompt bargein="false">\!voice gender="female"
    alrighty, your choice was
    <value  expr="hwynameArray[0]"/>
</prompt>
    </block>
  </form>

</vxml>


Highways.gsl


SDHIGHWAYS
  HIGHWAYS_LIST:d { <hwy "hwy"><hwyid $d.hwyid><hwyname $d.hwyname>}

HIGHWAYS_LIST
  HIGHWAYS:s { return($s) }

HIGHWAYS
  [
 
    [ ( five north) (?eye five north)] { return([<hwyid "1"> <hwyname "Five North"> ]) }
    [ ( five south) (?eye five south)]{ return([<hwyid "2"> <hwyname "Five South"> ]) }

]


Download the Code!

  Download the source code


  ANNOTATIONS: EXISTING POSTS
pacific_is_me
2/19/2006 11:53 PM (EST)
Line 17 of "Using NBest with a Multislot subgrammar" sample code missed the closed </audio> tag.

<form id="form1">
<field name="hwy" slot="hwy">
<audio>what highway would you like to take?
<property name="maxnbest" value="5"/>
kevinlim
2/20/2006 1:45 AM (EST)
Hey Duong,

Thanks for the input.  We're always thrilled when our customers help improve our documentation and support experience.

Best,
Kevin

login
  Downloadable GSL Subgrammar Library  |  TOC  |  J: grXML Grammars  

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