The Traffic Application Revisited

In "The WAP Traffic Application," I explained how I created a Wireless Markup Language (WML) traffic application that lets you render the current traffic speeds for San Diego on any Wireless Application Protocol (WAP) device and HTML browser. In this column, I use VoiceXML to take that application a step further and make it voice or punch-key driven and add voice response. (If you're not familiar with VoiceXML, see "Adding VoiceXML to our .NET Wireless Repertoire" and "Adding VoiceXML to Our .NET Wireless Repertoire, Part 2".)

To get the traffic data I need, I call a Web service that one of my colleagues developed ( see, "Two Web Services Solutions"). Then, I create an XML Document Object Model (XMLDOM) object similar to the following:

<!DOCTYPE vxml PUBLIC "-//Tellme Networks//Voice Markup Language
1.0//EN" "http://resources.tellme.com/toolbox/vxml-tellme.dtd">
<vxml>
<meta name="scoping" content="new"/>

<form id="speed">
   <block>
   <%
   Set xmlDoc = CreateObject("Microsoft.XMLDOM")
   
   xmlDoc.async = False
   xmlDoc.loadXML sXML
   
   Set objNodeList = xmlDoc.getElementsByTagName("z:row")
   . . .

This XMLDOM object provides access to the elements and the values I need from the XML that the GetTraffic method returns. Here's a sample of the XML that has the information I use:

<z:row TheFreeway='805 s' LocationDescription='Mira Mesa Blvd'
     Speed='71' SourceTime='2001-06-10T13:42:00'/>

Below is the basic format of the information I need the system to read back to the caller:

<audio>Freeway exit name</audio> <audio> Speed</audio>

But I thought it would sound a lot better with a human voice—not just for the traffic speed, but also for the freeway exits. So I changed the above audio tags to the following:

<audio src="exitname.wav">Freeway exit name</audio>
<audio src="speed.wav"> Speed</audio>

Instead of letting the computer read out the exits and speeds, I use my recorded voice. Instead of letting the computer read out the exits and speeds, I use my recorded voice. If the application can't retrieve the .wav files, it generates a computer voice rendition of the attributes from the node list.

I created .wav files for each freeway exit and for speeds from 0 mph to 86 mph. Then, the trick was to get the application to read each .wav file that matched the exit name and its corresponding speed in the node list. I accomplished this with a For loop that matches the node list index with the exit name and repeats the same process to get the speeds. I saved all the exit name .wav files in the same format (e.g., 2_0.wav, which translates to the first exit on freeway 805). Because the exits aren't the same for the north and south freeways and the east and west freeways, I created different folders for each direction.

Then, I massaged each node to get it into a format that made sense to the caller when the system reads the data back. I wrote a couple of functions that strip out the date, time, and speed from the data that the GetTraffic method returns. However, I ran into one little challenge. The node list usually includes four attributes and their values. For some reason, sometimes the Web service (which relies on an outside source for its data) returns no speed attribute value. Below is the code and function I developed:

For intExitNameCount = 0 To (objNodeList.length - 1)
           'See function below
strReturnSpeed = chkAttributeCount(objNodeList,intExitNameCount)

strReturnSpeedNoWav= strReturnSpeed 'If there is a problem
retrieving the wav file for the speed, then the actual value that
the Web service returns is used.

  for intSpeedMatch = 0 To 86
   if strReturnSpeed = intSpeedMatch then
strReturnSpeed = intSpeedMatch
    end if
next

'Data Output:
Response.write "<audio src = "exitNameWavs/" & strFolderDirection &
"/" & _   strFreeWayID & "_" & intExitNameCount & "'>" & _
      objNodelist.item(intExitNameCount).Attributes(1).Text & _
      " </audio> <audio src='speedWavs/" & _
      strReturnSpeed & ".wav'>" & strReturnSpeedNoWav & "</audio>"

next

Function chkAttributeCount(NodeObject,NodeNumber)
dim strSpeed

if NodeObject.item(NodeNumber).Attributes(2).name = "SourceTime"
then
  'This happens only if there are only 3 Attributes
    strTime = NodeObject.item(NodeNumber).Attributes(2).text
     strSpeed = "No Value   Returned"
    chkAttributeCount = strSpeed
else strSpeed = objNodelist.item(NodeNumber).Attributes(2).Text
    strTime = NodeObject.item(NodeNumber).Attributes(3).text
    chkAttributeCount = strSpeed
end if

End Function

To access the application, dial 1-800-555-8355. You will hear a Tellme advertisement for about 15 seconds. When you hear the Main Menu, dial 1-24671.

Please or Register to post comments.

IT/Dev Connections

Las Vegas
September 30th - October 4th

Paul ThurottOur Experts will show you:
• Common SQL Server
Problems
• Best Practices for T-SQL
• SQL Server Integration
Services
• Database Development

Come See Mike Otey & Tim Ford in Person!

Early Registration Now Open

From the Blogs
May 21, 2013
blog

A Common Misconception about MAXDOP

Out of the box, SQL Server is (and has been) able to take advantage of multiple processors/cores without any effort on behalf of administrators....More
May 9, 2013
blog

My ISO 8601-Compliant Signature 2

My family recently just "officially" announced that we're in the process of adopting a child from South Africa. We're quite excited, of course, but there's a ton of paperwork to do—along with the need for gobs of signatures....More
May 8, 2013
blog

Use SSIS for ETL from Hadoop

In this blog post, Mark Kromer walks you through using SSIS as a way to use ETL techniques using Microsoft's Hadoop on Windows (HDInsight) as a source using Hive connectors...More
SQL Server Pro Forums

Get answers to questions, share tips, and engage with the SQL Server community in our Forums.