Speech Recognition Grammar Specification: semantic results - grammar

I'm currently developing an application of Speech Recognition using Microsoft Kinect SDK. The goal of the application is to load any (valid) XML file containing the grammar and use it to process speech.
I'm in the process of testing the application by developing not so simple grammars and during that process I haven't figured out how to return specific semantic values, in particular names. For example, in the following grammar:
<grammar version="1.0" xml:lang="en-US" root="rootRule" tag-format="semantics/1.0-literals" xmlns="http://www.w3.org/2001/06/grammar">
<!-- Ask for person's related information (age, location, name, etc.) -->
<rule id="rootRule">
<one-of>
<!-- Ask person name -->
<item>
<tag>AnswerToNameQuestion</tag>
<one-of>
<item> my name is </item>
<item> people call me </item>
</one-of>
<ruleref uri="#names"/>
</item>
<!-- Ask person location -->
<item>
<tag>QuestionOfLocation</tag>
<one-of>
<item> do you know where is </item>
<item> can you tell me where </item>
<item> where did </item>
</one-of>
<ruleref uri="#names"/>
</item>
</one-of>
</rule>
<!-- Answer person name -->
<rule id="names">
<item>
<one-of>
<item> peter </item>
<item> john </item>
<item> danny </item>
</one-of>
</item>
</rule>
</grammar>
When a person says their name, I want the semantic to be the name of that person. For example, for the question "What is your name" (not included in this grammar), and a reply "My name is -insert name-", I wanted the semantic results to be the name of the person and not simply "AnswerToNameQuestion" semantic result that is being returned right now.
Any help would be greatly appreciated!

In the SpeechRecognized event handler. You can get the "textual sentence" if you query the event.Result.Text property instead of event.Result.Semantics.Value. You can use this second property to remove from text string the non-relevant portion.
For example, if somebody says "my name is Peter", inside SpeechRecognized event handler you will have:
event.Result.Text = "my name is Peter"
event.Result.Semantics.Value = "AnswerToNameQuestion"

Related

Extracting singleton value from xml list

I am familiar with extracting values from xml using SQL in SQL Server, but now I need to identify the parent node with a particular "key node" value and get the value from its "value node."
<example>
<item>
<key>skip</key>
<value>True</value>
</item>
<item>
<key>test</key>
<value>True</value>
</item>
<item>
<key>number</key>
<value />
</item>
<item>
<key>country</key>
<value>USA</value>
</item>
<item>
<key>Account Number</key>
<value>1111111111</value>
</item>
<item>
<key>website</key>
<value>stackoverflow</value>
</item>
<item>
<key>type</key>
<value>Customer</value>
</item>
</example>
If I want to get the account number I could use this sql statement:
SELECT xml.value('(example/item/value)[5]','varchar(30)')
Since the item node is 5th down on the list, the singleton will be 5. But what if the position of the account number node can change? I want to be able to identify the account number based on the condition that key = 'Account Number.'
In other words, I want to SELECT value where key = 'Account Number'
The trick is to specify WHICH "item" you want in brackets, by specifying a key/value that is unique to the item. In this case, you want the one where the "key" node has the text "Account Number". You'd express it like this:
SELECT #xml.value('(example/item[key="Account Number"]/value)[1]','varchar(30)')

Build New XML From Stored XML Value

We store rather large XML blobs (in an column of XML type) and I'm pursuing a skunkworks project to try to build up a subset of the XML on the fly when needed.
Let's say I have this XML blob stored in our database table in a given column:
<root>
<header>
<id>1</id>
<name id="foo">Name</name>
</header>
<body>
<items>
<addItem>
<val>1</val>
</addItem>
<observeItem>
<val>2</val>
</observeItem>
</items>
</body>
</root>
What I want to get out is this is to basically recreate the above document structure but only include one of the items children, so for example:
<root>
<header>
<id>1</id>
<name id="foo">Name</name>
</header>
<body>
<items>
<observeItem>
<val>2</val>
</observeItem>
</items>
</body>
</root>
If I were interested in just the observeItem record (the items element can have any number of children, but I'll only ever be interested in a single one of them).
I know I can do something like SELECT #XML.query('//items/child::*[2]') to get just a given child item, but how would I build up the full original document in a query with just one of those children?
I've come up with a solution, but I'm not entirely pleased with it:
DECLARE #XML XML = '
<root>
<header>
<id>1</id>
<name id="foo">Name</name>
</header>
<body>
<items>
<addItem>
<val>1</val>
</addItem>
<observeItem>
<val>2</val>
</observeItem>
</items>
</body>
</root>'
DECLARE #NthChild INT = 2
SELECT
#XML.query('//header'),
#XML.query('//items/child::*[sql:variable("#NthChild")]') AS 'items'
FOR XML PATH('root')
I don't like having to specify the root explicitly nor the items, but I think this approach could get me by.

Batch processing Google Contact Groups with API (php)

I'm trying to do batch processing of Google Contact groups. I have batch processing working for the actual contacts, but groups are not behaving. The XML that I send to Google is:
<?xml version='1.0' encoding='UTF-8'?>
<feed xmlns='http://www.w3.org/2005/Atom'
xmlns:gContact='http://schemas.google.com/contact/2008'
xmlns:gd='http://schemas.google.com/g/2005'
xmlns:batch='http://schemas.google.com/gdata/batch'>
<entry>
<batch:id>create</batch:id>
<batch:operation type='insert'/>
<category scheme='http://schemas.google.com/g/2005#kind'
term='http://schemas.google.com/contact/2008#group'/>
<title type='text'>Status:Followup 1</title>
<content type='text'>Status:Followup 1</content>
</entry>
</feed>
The response I got back from google was:
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"
xmlns:batch="http://schemas.google.com/gdata/batch"
xmlns:gContact="http://schemas.google.com/contact/2008"
xmlns:gd="http://schemas.google.com/g/2005">
<id>https://www.google.com/m8/feeds/contacts/awallace%40ihouseweb.com/full/batch/1430425819721000</id>
<updated>2015-04-30T20:30:19.721Z</updated>
<title type="text">Batch Feed</title>
<entry gd:etag=""SHs-ezVSLit7I2A9XRVTFE8PTwU."">
<batch:id>create</batch:id>
<batch:operation type="insert"/>
<batch:status code="201" reason="Created."/>
<id>http://www.google.com/m8/feeds/contacts/awallace%40ihouseweb.com/base/4b9f4f69095d670d</id>
<updated>2015-04-30T20:30:19.553Z</updated>
<app:edited xmlns:app="http://www.w3.org/2007/app">2015-04-30T20:30:19.553Z</app:edited>
<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/contact/2008#contact"/>
<title/>
<content>Status:Followup 1</content>
<link rel="http://schemas.google.com/contacts/2008/rel#photo" type="image/*"
href="https://www.google.com/m8/feeds/photos/media/awallace%40ihouseweb.com/4b9f4f69095d670d"/>
<link rel="self" type="application/atom+xml" href="https://www.google.com/m8/feeds/contacts/awallace%40ihouseweb.com/full/4b9f4f69095d670d"/>
<link rel="edit" type="application/atom+xml"
href="https://www.google.com/m8/feeds/contacts/awallace%40ihouseweb.com/full/4b9f4f69095d670d"/>
</entry>
</feed>
(note, there were actually 4 groups in my batch, but the results were identical).
The groups in my account were unchanged. I have successfully added and deleted groups one at a time (without the batch syntax/url). The result XML here says explicitly that the group was created (), but the title element is empty in the return. ()
Any ideas?
Thanks,
Andy
I had a similar problem when batch creating groups. My problem was I had no entry for gd:extendedProperty:
eg:
<?xml version="1.0"?>
<feed xmlns:atom="http://www.w3.org/2005/Atom" xmlns:gd="http://schemas.google.com/g/2005" xmlns:gContact="http://schemas.google.com/contact/2008" xmlns:batch="http://schemas.google.com/gdata/batch">
<entry>
<batch:id>create</batch:id>
<batch:operation type="insert"/>
<atom:category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/contact/2008#group"/>
<atom:title type="text">Test 1</atom:title>
<gd:extendedProperty name="Test 1">
<info>Test 1</info>
</gd:extendedProperty>
</entry>
...
</feed>
The XML markup you have appears to be for updating an existing group. Have a look at the documentation for more info:
https://developers.google.com/google-apps/contacts/v3/#batch_operations_for_contact_groups

sql + xquery to delete multiple parent nodes

In the below xml i have three 5 /Item elements, 4 of which have a Blob child element. I want to delete the elements that have a child Blob element but only where Item/#Name has the text "Blob" in it.
<Items>
<Item Name="Blob123">
<Blob/>
</Item>
<Item Name="Blob124">
<Blob/>
</Item>
<Item Name="Blob125">
<Blob/>
</Item>
<Item Name="Blob126">
</Item>
<Item Name="Xyz126">
<Blob/>
</Item>
</Items>
This query returns the 3 /Item elements named 'Blob%' and with a child /Blob element just fine.
select xmlVal.query('(/Items/Item[contains(#Name, "Blob")]/Blob/..)')
However when i attempt to delete those element using this xquery:
select xmlVal.modify('delete (/Items/Item[contains(#Name, "Blob")]/Blob/..)')
I get: Incorrect use of the XML data type method 'modify'. A non-mutator method is expected in this context.
What am i doing wrong.
In case it helps others, to fix this i need to use update/set and also needed to change the xpath slightly
update table1
set xmlVal.modify('delete (/Items/Item[contains(#Name, "Blob")][Blob])')

vxml: defining grammars with equivalent inputs

I am using an engine based on TellMe. I have seen examples of grammars where the user can say one of a few different things that are considered the same. However, all the examples i've seen have been for in-line grammars (which dont work with the vxml engine im using). I want to know how i can change my .grxml file to do this. This is the file:
<?xml version="1.0"?>
<!-- created by Matthew Murdock. Grammars for speech rec menus -->
<grammar xmlns="http://www.w3.org/2001/06/grammar" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2001/06/grammar http://www.w3.org/TR/speech-grammar/grammar.xsd" xml:lang="en" version="1.0" mode="voice" scope="dialog" tag-format="semantics/1.0.2006">
<rule id="keep">
<one-of>
<item>exit</item>
<item>exit the system</item>
<item>another</item>
<item>another mailbox</item>
<item>play</item>
<item>play back</item>
</one-of>
</rule>
</grammar>
instead of having 6 items, i want to have 3 items, each having two possible utterances. Any ideas on how i can do this?
A more compact form:
<rule id="exit">
exit <item repeat="0-1">the system</item>
<tag>out.result = "exit"</tag>
</rule>
<rule id="play">
play <item repeat="0-1">back</item>
<tag>out.result = "play"</tag>
</rule>
The answers you want are in the SISR specification which provides a mechanism for attaching meaning to input paths. Rewriting your example:
<?xml version="1.0"?>
<grammar xmlns="http://www.w3.org/2001/06/grammar" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2001/06/grammar http://www.w3.org/TR/speech-grammar/grammar.xsd" xml:lang="en" version="1.0" mode="voice" scope="dialog" tag-format="semantics/1.0-literals">
<rule id="keep">
<one-of>
<item>
<one-of>
<item>exit</item>
<item>exit the system</item>
</one-of>
<tag>exit</tag>
</item>
<item>
<one-of>
<item>another</item>
<item>another mailbox</item>
</one-of>
<tag>another</tag>
</item>
<item>
<one-of>
<item>play</item>
<item>play back</item>
</one-of>
<tag>play</tag>
</item>
</one-of>
</rule>
</grammar>
Several things to know:
I chose the literal tag format (notice the tag-format attribute of the grammar element). It could have also been implemented using "semantics/1.0" and the contents of the tag would have looked like: out="exit";
TellMe tag-format values may need to be different, but their development guide implies they follow the standards.
Once you have it working, don't hesitate to create filler grammars (in SRGS speak, rules). Filler rules would be rules without any SI (no tag elements) and contain common phrases people add to responses. For example, a trailing rule that could be added at the end of your grammar:
</one-of>
<item repeat="0-1"><ruleref uri="#trailing"/></item>
</rule>
<rule id="trailing>
<one-of>
<item>please</item>
<item>thank you</item>
</one-of>
</rule>
</grammar>
This would support more natural types of responses. This may or may not be important depending on your calling base. Filler grammars can be very large, but tend to be highly reusable. You can also add filler at the beginning of input. In rich speech applications, a the most significant gain in the tuning process involves updating the grammar to contain the actual phrases spoken by the caller versus what the developer or VUI designer thought would be spoken.
I figured it out. I changed my grammar to look like this:
<?xml version="1.0"?>
<grammar xmlns="http://www.w3.org/2001/06/grammar" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.w3.org/2001/06/grammar http://www.w3.org/TR/speech-grammar/grammar.xsd" xml:lang="en" version="1.0" mode="voice" scope="dialog" tag-format="semantics/1.0-literals">
<rule id="keep">
<one-of>
<item><ruleref id="#exit"/></item>
<item><ruleref id="#play"/></item>
</one-of>
</rule>
<rule id="exit">
<one-of>
<item>exit</item>
<item>exit the system</item>
</one-of>
<tag>out.result = "exit"</tag>
</rule>
<rule id="play">
<one-of>
<item>play</item>
<item>play back</item>
</one-of>
<tag>out.result = "play"</tag>
</rule>
</grammar>
Then, back in my script instead of basing my actions on callerInput (the variable specified in the <field> tag), i based them off of callerInput$.interpretation which holds xml containing whatever i assigned out.result to in the <tag> element of the grammar.
I guess it makes sense to base your actions on the "interpretation" and not the caller's literal input.
NOTE: Because we are working with our own vxml engine we were able to create a method for extracting the interpretation value out of the xml.