VoiceXML 2.1 Development Guide Home  |  Frameset Home

  SRGS-SISR: Subgrammars  |  TOC  |  K: Custom Features  

Inline XML Subgrammars

XML subgrammar structures can also be included inline, although it does seem to create additional clutter within your code. It is advisable to first define your grammar as a separate file,  and then include it within the VoiceXML code when you are satisfied that it is working properly, thus keeping your code as modular as possible. Do keep in mind the filesize limitation of 100k per document when designing your application; a good rule of thumb is to keep larger subgrammar structures as external documents rather than including them inline. That being said, a grXML subgrammar can be ported from an external document to an inline structure with absolutely no change to the grammar structure, and but one or two minor changes to the VoiceXML code:



<?xml version="1.0"?>
<vxml version = "2.0" xmlns="http://www.w3.org/2001/vxml">
<form>
  <field name="F_1">
      <prompt>
        What is my name, biz nitch?it
      </prompt>

  <grammar xml:lang="en-US" root = "TOPLEVEL">
    <rule id="TOPLEVEL" scope="public">
      <item>
<!-- FIRST NAME RETURN -->

        <item repeat="0-1">
          <ruleref uri="#FIRSTNAME"/>
          <tag>out.firstNameSlot=rules.FIRSTNAME.firstNameSubslot</tag>
        </item>
<!-- MIDDLE NAME RETURN -->

        <item repeat="0-1">
          <ruleref uri="#MIDDLENAME"/>
          <tag>out.middleNameSlot=rules.MIDDLENAME.middleNameSubslot</tag>
        </item>
<!-- LAST NAME RETURN -->

          <ruleref uri="#LASTNAME"/>
          <tag>out.lastNameSlot=rules.LASTNAME.lastNameSubslot</tag>
        </item>

<!-- TOP LEVEL RETURN-->
          <tag> out.F_1= out.firstNameSlot + out.middleNameSlot + out.lastNameSlot </tag>
    </rule>

  <rule id="FIRSTNAME" scope="public">
  <one-of>
    <item> matt<tag>out.firstNameSubslot="matthew";</tag></item>
    <item> dee <tag> out.firstNameSubslot="dee ";</tag></item>
    <item> jon <tag> out.firstNameSubslot="jon ";</tag></item>
    <item> george <tag>out.firstNameSubslot="george ";</tag></item>
    <item> billy <tag> out.firstNameSubslot="billy ";</tag></item>
  </one-of>
  </rule>

  <rule id="MIDDLENAME" scope="public">
  <one-of>
    <item> bon <tag>out.middleNameSubslot="bon ";</tag></item>
    <item> double ya <tag> out.middleNameSubslot="w ";</tag></item>
    <item> dee <tag> out.middleNameSubslot="dee ";</tag></item>
  </one-of>
  </rule>

  <rule id="LASTNAME" scope="public">
  <one-of>
    <item> henry <tag> out.lastNameSubslot="henry "; </tag></item>
    <item> ramone <tag> out.lastNameSubslot="dee ";  </tag></item>
    <item> jovi <tag> out.lastNameSubslot="jovi ";  </tag></item>
    <item> bush <tag> out.lastNameSubslot=""bush ";  </tag></item>
    <item> williams <tag> out.lastNameSubslot="williams "; </tag></item>
  </one-of>
  </rule>

</grammar>

    <filled>
      <prompt>
          You said that yo daddy is <value expr="F_1"/>.
      </prompt>
    </filled>
  </field>
  </form>
</vxml>


Download the Code!

  Download the source code


  ANNOTATIONS: EXISTING POSTS
mf.mctear
5/31/2007 6:55 AM (EDT)
I have been trying to use <tag> to return a different value from the one recognised. This works for a simple grammar e.g.
<rule id="FIRSTNAME" scope="public">
<item> alexander
<tag> return ("henry ") </tag>
</item>
</rule>
- returns "henry"

but does not work if this rule is called as a sub-grammar. I have tried different permutations of your example of an inline sub-grammar. This is a simple version:

<?xml version="1.0"?>
<vxml version = "2.0" xmlns="http://www.w3.org/2001/vxml">

<form>
<field name="F_1" >
<prompt>
What is my name?
</prompt>

<grammar xml:lang="en-US" root = "TOPLEVEL">

<rule id="TOPLEVEL" scope="public">
<item>
<ruleref uri="#FIRSTNAME"/>
</item>
</rule>

<rule id="FIRSTNAME" scope="public">
<item> alexander
<tag> return ("henry ") </tag>
</item>
</rule>
</grammar>
<filled>
<prompt>
You said that my name is <value expr="F_1"/>.
</prompt>
</filled>
</field>
</form>
</vxml>

- returns 'alexander'

How can I pass the value 'henry' up to TOPLEVEL?
VoxeoDante
5/31/2007 1:35 PM (EDT)
Hello,

In order to access the interpretation value in a subgrammar you have to assign the value to a slot. When you assign a slot, it allows the interpretation value to be passed back up to the toplevel rule. Without the slot assignment the subgrammar will only return the utterance value and not the interpretation value. The code should be formatted in this way.

<?xml version="1.0"?>
<vxml version = "2.0" xmlns="http://www.w3.org/2001/vxml">

<form>
<field name="F_1" >
<prompt>
What is my name?
</prompt>

<grammar xml:lang="en-US" root = "TOPLEVEL">

<rule id="TOPLEVEL" scope="public">
<item>
<ruleref uri="#FIRSTNAME"/>
</item>
</rule>

<rule id="FIRSTNAME" scope="public">
<one-of>
<item> alexander
<!--  Assigns the value to a slot -->
<tag><![CDATA[ <F_1 "henry"> ]]> </tag>

</item>
</one-of>
</rule>
</grammar>
<filled>
<prompt>
You said that my name is <value expr="F_1"/>.
</prompt>
</filled>
</field>
</form>
</vxml>

If you have any further questions please let me know.

All the Best,
Dante Vitulano
mf.mctear
6/2/2007 12:14 PM (EDT)
Thanks - that works fine.
Now I have another problem - I want to assign values from the same subgrammar to different slots. Based on the Nuance specification I have the followiung grammar which relates to a mixed-initiative form:

banking_test.grxml

<?xml version= "1.0"?>
<grammar xmlns="http://www.w3.org/2001/06/grammar"
xml:lang="en-US" root = "transfer">

<rule id="transfer" scope="public">
<item> from <ruleref uri="#account"/>
<tag> assign (s $return) </tag>
</item>
<item> to <ruleref uri="#account"/>
<tag> assign (d $return) </tag>
</item>
<tag> <![CDATA[<source $s> <destination $d>]]> </tag>
</rule>

<rule id = "account" scope = "public">
  <one-of>
  <item> savings  </item>
  <item> current  </item>
  </one-of>
</rule>

</grammar>

transfer_mixed.vxml

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

<form scope="dialog">
<grammar src="banking_test.grxml#transfer" mode="voice"/>

<initial name="start">
<prompt>
say savings current
</prompt>
</initial>

<field name="source" modal="false">
  <prompt>
  what is the source account?
  </prompt>
<grammar src="banking_test.grxml#account" mode="voice"/>
</field>

<field name="destination" modal="false">
  <prompt>
  what is the destination account?
  </prompt>

  <grammar src="banking.grxml#account" mode="voice"/>

  </field>

<filled>
you said from <value expr="source"/> to  <value expr="destination"/>
</filled>

  </form>
</vxml>

but I can't get it to fill the slots.
Your help would be much appreciated.
VoxeoDante
6/4/2007 12:53 PM (EDT)
Hello,

I will be working on an answer for you, but I want to make sure you understand mixed initiative subgrammars are time consuming. This matter will take some time to resolve. I will update this ticket as soon as I have an answer for you.

All the Best,
Dante Vitulano
MattHenry
6/4/2007 4:59 PM (EDT)


Hi there,

I think that the problem here stems from a misunderstanding of how the top-level rules work in conjunction with a mixed-initiative document structure. In checking the tutorial on mixed init, take note of the following:


1) The form-scoped grammar references the rule that has *both* slots defined, (ie what you currently have in your grammar).


2) There are more than one top-level rule possibility defined in the grammar:

a) Utterance #1, *and* Utterance #2
b) Utterance #1 only
c) Utterance #2 only


3) Each field references a sub-rule that defines the utterance/interp value specifically for the field.

Keeping these facts firmly in mind, it's clear that the grammar needs some additional rules defined, and that the grammar references in the VXML need to be changed to reflect this.


Hope that this helps to steer you in the right direction,

~Matthew Henry


mf.mctear
6/5/2007 2:38 PM (EDT)
Thanks for the help so far. Looking at this rule:
<rule id="transfer" scope="public">
<item> from <ruleref uri="#account"/>
<tag> assign (s $return) </tag>
</item>
<item> to <ruleref uri="#account"/>
<tag> assign (d $return) </tag>
</item>
<tag> <![CDATA[<source $s> <destination $d>]]> </tag>
</rule>
I had thought that e.g. with input 'savings current' when the sub-grammar 'account' was called, it would assign 'savings' to 's' via $return then 'current' to 'd', then s and d would be assigned to 'source' and 'destination' respectively. This is how I understood the example in the Nuance documentation on XML grammars. Is there still something missing?
I can get it to work by having separate subgrammars for source account and destination account, but I wanted generality by having the account types listed only once and then assigning their values through the top level rule.
MattHenry
6/6/2007 4:11 PM (EDT)

Hi again,

As both "savings" and "current" are seperate <items> defined in the same rule, then I don't see how this would even be a valid utterance: chances are, that we would get a "nomatch" event, (or at best, "savings" would be recognized, while "current" would be ignored. Also, be aware that we need to define explicit slot names to the grammar returns, and that the "assign (d $return)" stuff doesn't really come into play unless we are concatenating seperate utterances from subgrammars into a single string value.

In an effort to help illustrate what your grammar structure should be modeled after I have attached some VXML and grammars that should help steer you towards a path of Mixed-Initiative Righteousness. If, after reviewing this code, you have any remaining questions, please do let me know what I can do to help out.

Regards,

~Matthew henry
roman3m
5/4/2009 1:25 AM (EDT)
I am currently developing a grammar to recognize three letters followed by two numbers.  I would like some help from you to somehow increase accuracy and highligh any errors I am falling in.
Specially, I am concern about returning the ABC12 string to my application.  Thanks very much.

-------------attached grammar
<?xml version="1.0" encoding="UTF-8" ?> 
<vxml xmlns="http://www.w3.org/2001/vxml" version="2.0">
  <var name="MyResult" />
 
<form>
<field name="TestField">
<grammar xml:lang="en-AU" mode="voice" root="alphanum_6">
 
  <rule id="alphanum_6">
    <one-of>
        <item>
          <ruleref uri="#firstCharacter"/>
          <tag>tag = oneCharacter.tag</tag>
        </item>
        <item>
          <ruleref uri="#secondCharacter"/>
          <tag>tag = twoCharacters.tag</tag>
        </item>
        <item>
          <ruleref uri="#thirdCharacter"/>
          <tag>tag = threeCharacters.tag</tag>
        </item>
<item>
          <ruleref uri="#fourthCharacter"/>
          <tag>tag = fourCharacters.tag</tag>
        </item>
<item>
          <ruleref uri="#fifthCharacter"/>
          <tag>tag = fiveCharacters.tag</tag>
        </item>
      </one-of>
    </rule>

    <rule id="firstCharacter">
      <ruleref uri="#alphabet"/>
      <tag>tag = alphabet.tag</tag>
    </rule> id="secondCharacters">
      <ruleref uri="#alphabet"/>
      <tag>an1 = alphabet.tag</tag>
      <ruleref uri="#alphabet"/>
      <tag>an2 = alphabet.tag</tag>
      <tag> tag = (an1+an2); </tag>
  </rule>

    <rule id="thirdCharacter">
      <ruleref uri="#alphabet"/>
      <tag>an1 = alphabet.tag</tag>
      <ruleref uri="#alphabet"/>
      <tag>an2 = alphabet.tag</tag>
      <ruleref uri="#alphabet"/>
      <tag>an3 = alphabet.tag</tag>
      <tag> tag = (an1+an2+an3); </tag>
  </rule>

  <rule id="fourthCharacter">
      <ruleref uri="#alphabet"/>
      <tag>an1 = alphabet.tag</tag>
      <ruleref uri="#alphabet"/>
      <tag>an2 = alphabet.tag</tag>
      <ruleref uri="#alphabet"/>
      <tag>an3 = alphabet.tag</tag>
      <ruleref uri="#digit"/>
      <tag>an4 = digit.tag</tag>
      <tag> tag = (an1+an2+an3+an4); </tag>
  </rule>

  <rule id="fifthCharacter">
      <ruleref uri="#alphabet"/>
      <tag>an1 = alphabet.tag</tag>
      <ruleref uri="#alphabet"/>
      <tag>an2 = alphabet.tag</tag>
      <ruleref uri="#alphabet"/>
      <tag>an3 = alphabet.tag</tag>
      <ruleref uri="#alphabet"/>
      <tag>an4 = digit.tag</tag>
      <ruleref uri="#digit"/>
      <tag>an5 = digit.tag</tag>
      <tag> tag = (an1+an2+an3+an4+an5); </tag>
  </rule>
 
  <rule id="alphabet">
      <one-of>
<item>a<tag>alphabet="a"</tag></item>
        <item>b<tag>alphabet="b"</tag></item>
        <item>c<tag>alphabet="c"</tag></item>
        <item>d<tag>alphabet="d"</tag></item>
        <item>e<tag>alphabet="e"</tag></item>
        <item>f<tag>alphabet="f"</tag></item>
        <item>g<tag>alphabet="g"</tag></item>
        <item>h<tag>alphabet="h"</tag></item>
        <item>i<tag>alphabet="i"</tag></item>
        <item>j<tag>alphabet="j"</tag></item>
        <item>k<tag>alphabet="k"</tag></item>
        <item>l<tag>alphabet="l"</tag></item>
        <item>m<tag>alphabet="m"</tag></item>
        <item>n<tag>alphabet="n"</tag></item>
        <item>o<tag>alphabet="o"</tag></item>
        <item>p<tag>alphabet="p"</tag></item>
        <item>q<tag>alphabet="q"</tag></item>
        <item>r<tag>alphabet="r"</tag></item>
        <item>s<tag>alphabet="s"</tag></item>
        <item>t<tag>alphabet="t"</tag></item>
        <item>u<tag>alphabet="u"</tag></item>
        <item>v<tag>alphabet="v"</tag></item>
        <item>w<tag>alphabet="w"</tag></item>
        <item>x<tag>alphabet="x"</tag></item>
        <item>y<tag>alphabet="y"</tag></item>
        <item>z<tag>alphabet="z"</tag></item>
      </one-of>
  </rule>

<rule id="digit">
      <one-of>
<item>0<tag>alphabet="0"</tag></item>
<item>1<tag>alphabet="1"</tag></item>
        <item>2<tag>alphabet="2"</tag></item>
        <item>3<tag>alphabet="3"</tag></item>
        <item>4<tag>alphabet="4"</tag></item>
        <item>5<tag>alphabet="5"</tag></item>
        <item>6<tag>alphabet="6"</tag></item>
        <item>7<tag>alphabet="7"</tag></item>
        <item>8<tag>alphabet="8"</tag></item>
        <item>9<tag>alphabet="9"</tag></item> 
      </one-of>
  </rule>

</grammar>

<filled>
  <assign name="myResult" expr="application.lastresult$.interpretation.tag" />
  <exit namelist="myResult" />
  </filled>
  </field>
  </form>
  </vxml>

voxeoJeffK
5/4/2009 3:30 AM (EDT)
Hello,

I've attached an alphanumeric grammar that should work for you. This type of grammar capture can be very difficult to obtain desired results. You may be interested in reading the following articles written by one of our grammar experts :

  http://blogs.voxeo.com/voxeodeveloperscorner/?p=29

  http://blogs.voxeo.com/voxeodeveloperscorner/2008/05/20/certified-tech-tip-alpha-numeric-voice-recognition-grammars-part-two/

Regards,
Jeff Kustermann
Voxeo Support
amitsood
10/29/2009 6:17 PM (EDT)
VIN (Vehicle Identification Number) is alpha numeric field. Are there any pre-built dialog module or grammars to collect the VIN number? If not, what is the best way to collect a VIN number on an IVR system. Any suggestions are welcome.
Thanks
Amit
voxeoblehn
10/29/2009 6:48 PM (EDT)
Hello Amit,

Your best bet would be to reference the forum post right before this one made by JeffK, as this provides an alphanumeric grammar (attached) and additional documentation on this topic.

Upon reviewing the referenced articles, we would be happy to answer any direct grammars you may have.

Best Regards,

Brian Lehnen
Voxeo Support
jalbersmead
7/2/2010 4:07 PM (EDT)
It seems that the example code above is not parsing the <tag></tag> content but is instead returning the enclosed text verbatim.  I took the code from the example above, saved it to my local server (Prophecy 9.0.42495.0) and added a logging line to see what F_1 was just before the final <prompt> tag to see if the logged and spoken versions of the F_1 result were the same and they both come back with:

You said that yo daddy isout.F_1= out.firstNameSlot + out.middleNameSlot + out.lastNameSlot.

The relevant log data is below:

MRS/ijam/2010.07.02.12.47.03.414/1:4c9ba7a719a5b451959612b31db35817-2494732330-091b3760-09549830-00000079:00000001:1/USER/SRE::PR/Partial result: george
MRS/ijam/2010.07.02.12.47.03.950/1:4c9ba7a719a5b451959612b31db35817-2494732330-091b3760-09549830-00000079:00000001:1/USER/SRE::PR/Partial result: george henry
MRS/ijam/2010.07.02.12.47.04.847/1:4c9ba7a719a5b451959612b31db35817-2494732330-091b3760-09549830-00000079:00000001:1/USER/SRE::PR/End of speech detected, frame 226 [type=HMM BEST WORD].
MRS/ijam/2010.07.02.12.47.04.847/1:4c9ba7a719a5b451959612b31db35817-2494732330-091b3760-09549830-00000079:00000001:1/USER/SRE::PR/End of speech was received (frame=226).
MRS/ijam/2010.07.02.12.47.04.847/1:4c9ba7a719a5b451959612b31db35817-2494732330-091b3760-09549830-00000079:00000001:1/USER/SRE::PR/Final result: george henry; confidence 58; min confidence 0
MRS/ijam/2010.07.02.12.47.04.847/1:4c9ba7a719a5b451959612b31db35817-2494732330-091b3760-09549830-00000079:00000001:1/USER/SRE::PR/Done with Run() -- result=0; calling Stop()
MRS/ijam/2010.07.02.12.47.04.847/1:4c9ba7a719a5b451959612b31db35817-2494732330-091b3760-09549830-00000079:00000001:1/USER/SRE::PR/Changing ASR state from Recognizing to Complete
MRS/ijam/2010.07.02.12.47.04.847/1:4c9ba7a719a5b451959612b31db35817-2494732330-091b3760-09549830-00000079:00000001:1/DEBUG/SRE::PR/Starting Analyze()
MRS/ijam/2010.07.02.12.47.04.847/1:4c9ba7a719a5b451959612b31db35817-2494732330-091b3760-09549830-00000079:00000001:1/USER/SRE::PR/Received final result: george henry
MRS/ijam/2010.07.02.12.47.04.847/1:4c9ba7a719a5b451959612b31db35817-2494732330-091b3760-09549830-00000079:00000001:1/USER/SRE::PR/Changing ASR state from Complete to Idle
...
VXML/ijam/2010.07.02.12.47.04.853/1:4c9ba7a719a5b451959612b31db35817:afae5c7d1e0b6b3a710d3602ca618450:1/USER/com.voxeo.motorola.mrcp.MrcpGrammarUtils/Speech recognition result 0= | _interpretationconfidence=0.58 | _confidence=0.58 | vmlslot0= out.F_1= out.firstNameSlot + out.middleNameSlot + out.lastNameSlot  | _grammar_id=0 | _inputmode=voice | _utterance=george henry
VXML/ijam/2010.07.02.12.47.04.855/1:4c9ba7a719a5b451959612b31db35817:afae5c7d1e0b6b3a710d3602ca618450:1/USER/com.mot.icsd.voxml.core.TraceStmt/XML(NameCode.xml, line 64): filled
VXML/ijam/2010.07.02.12.47.04.855/1:4c9ba7a719a5b451959612b31db35817:afae5c7d1e0b6b3a710d3602ca618450:1/USER/com.mot.icsd.voxml.core.TraceStmt/XML(NameCode.xml, line 65): log expr="'******F_1: '+F_1"
VXML/ijam/2010.07.02.12.47.04.855/1:4c9ba7a719a5b451959612b31db35817:afae5c7d1e0b6b3a710d3602ca618450:1/USER/com.mot.icsd.voxml.core.LogStmt/LOG: ******F_1:  out.F_1= out.firstNameSlot + out.middleNameSlot + out.lastNameSlot
VXML/ijam/2010.07.02.12.47.04.855/1:4c9ba7a719a5b451959612b31db35817:afae5c7d1e0b6b3a710d3602ca618450:1/USER/com.mot.icsd.voxml.core.TraceStmt/XML(NameCode.xml, line 66): prompt
VXML/ijam/2010.07.02.12.47.04.856/1:4c9ba7a719a5b451959612b31db35817:afae5c7d1e0b6b3a710d3602ca618450:1/USER/com.mot.mrcp.ec.MRCPExecutionContext/Flushing Prompts
VXML/ijam/2010.07.02.12.47.04.856/1:4c9ba7a719a5b451959612b31db35817:afae5c7d1e0b6b3a710d3602ca618450:1/USER/com.mot.mrcp.ec.MRCPExecutionContext/TTS: You said that yo daddy isout.F_1= out.firstNameSlot + out.middleNameSlot + out.lastNameSlot.

I've been reading over the VXML and grXML grammar docs but apart from finding other ways of enclosing the data (i.e. CDATA )I can't get it to parse the content of the <tag> tag.  Also, the "Download the source code" link is broken above so I've been copying the code from this page instead in case the download file and the code above differ.
VoxeoDante
7/2/2010 6:11 PM (EDT)
Hello,

I tested this my self, and I am afraid that I am not seeing the same results.  I suspect that there are some copy/paste artifacts left here.  I am going to attach the code here for you.  Can you give this a shot and let me know if this works?

Regards,
Dante Vitulano
Customer Obsession Team
Voxeo Corp.
megallo
2/28/2012 11:11 PM (EST)
Howdy,

The URL under the link for "Download the source code" results in a 404 Not Found.

Cheers,
Meg
VoxeoDante
3/5/2012 11:59 AM (EST)
Hello Meg,

I apologize for the inconvenience.  I will have someone track down the sourcecode for this project  and get it linked back up.  Once we get that fixed, we will post back here and let you know.

Please let us know if there are any questions in the meantime.

Regards,
Danté Vitulano
Hosted Solutions Engineer

[url=http://www.voxeo.com/university/home.jsp]
[img=http://www.voxeo.com/images/logos/VoxeoUnivLogo.png/]
[/url]
[b][color=blue]Interested in Training? Visit the Voxeo University Page to Learn More![/color][/b]

login
  SRGS-SISR: Subgrammars  |  TOC  |  K: Custom Features  

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