Using XSL Transformations to produce VoiceXML

This example shows how to use the standard XSL Transformations to transform an XML file into VoiceXML and HTML. It demonstrates the use of Perl and Microsoft's Active Server Pages to load XML documents and XSLT stylesheets.

XSL Transformations are ideal for purposing raw data into a variety of output formats including HTML, VoiceXML, and print. Alternatively, you can use the data element to load the XML directly from a static VoiceXML document.

Try It!
  1. Set your Application URL to http://studio.247-inc.net/library2/code/ex-118/index.vxml
  2. Call the number shown in VXML Tools page
  3. Sign in, and play!

An XSLT stylesheet is used to transform an existing XML file into the desired format (VoiceXML or HTML) The default output format is VoiceXML, the format that the Tellme voice browser parses and executes. The server side script loads both the XML document and the specified XSLT document to perform the transformation.

From your Web browser, you can call the server-side script using the following URLs:

; output the dev list in VoiceXML 2.0 format (same as no query string)
http://studio.tellme.com/library2/code/ex-118/loaddevs.cgi?format=0
; ouput the dev list in HTML format
http://studio.tellme.com/library2/code/ex-118/loaddevs.cgi?format=1

The Tellme developer data set in this sample is loaded from a static XML file. You can easily write a CGI script to pull data from a database and to reformat that data as XML that your XSLT can transform.

<?xml version="1.0"?>
<devs>
   <dev>
      <id>10000</id>
      <company>tell me networks</company>
      <contact>tell me bob</contact>
      <country>usa</country>
   </dev>
   <dev>
      <id>20000</id>
      <company>slappy inc</company>
      <contact>john doe</contact>
      <country>france</country>
   </dev>
</devs> 

The following XSLT stylesheet is used to transform the sample data set shown above into VoiceXML 2.0 format.

<!-- 
Tellme Studio Code Example 118 
Copyright (C) 2000-2001 Tellme Networks, Inc. All Rights Reserved. 

THIS CODE IS MADE AVAILABLE SOLELY ON AN "AS IS" BASIS, WITHOUT WARRANTY 
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, 
WARRANTIES THAT THE CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A 
PARTICULAR PURPOSE OR NON-INFRINGING. 
--> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" omit-xml-declaration="yes" />

<!-- root template -->
<xsl:template match="/">
	<xsl:apply-templates select="devs"/>
</xsl:template>

<!-- handle the devs node -->
<xsl:template match="devs">
<vxml version="2.0">
<form id="init">
  <block>
  <log>Listing Studio Developers</log>
  <audio>Listing Studio Developers </audio>
     			
  <!-- walk each of the dev nodes -->
  <xsl:for-each select="dev">
     <!-- use audio to output each node contained by dev followed by a pause -->
     <audio>Developer i d is <xsl:value-of select="id" /></audio>
  	 <break time="750ms"/>

  	 <audio>Company name is <xsl:value-of select="company" /></audio>  			
  	 <break time="750ms"/>

  	 <audio>Contact name is <xsl:value-of select="contact" /></audio>
  	 <break time="750ms"/>

     <audio>Country name is <xsl:value-of select="country" /></audio>
  	 <break time="750ms"/>
  </xsl:for-each>

  <log> done with list </log>
  <exit/>
  </block>
</form>
</vxml>
</xsl:template>
	
</xsl:stylesheet>

The following XSLT stylesheet is used to transform the sample data set shown above into HTML format.

<!-- 
Tellme Studio Code Example 118 
Copyright (C) 2000-2001 Tellme Networks, Inc. All Rights Reserved. 

THIS CODE IS MADE AVAILABLE SOLELY ON AN "AS IS" BASIS, WITHOUT WARRANTY 
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, 
WARRANTIES THAT THE CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A 
PARTICULAR PURPOSE OR NON-INFRINGING. 
--> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" omit-xml-declaration="yes" />

<!-- root template -->
<xsl:template match="/">
	<xsl:apply-templates select="devs"/>
</xsl:template>

<!-- handle the devs node -->
<xsl:template match="devs">
<html>
<head><title>Listing Studio Developers </title></head>
<style>
table.report th {
   background-color: #cccccc; font-family: arial; font-size: 10pt;
}
table.report td {
   background-color: #dddddd; font-family: arial; font-size: 10pt;
}
</style>

<body>
<table cellspacing="2px" cellpadding="5px" class="report">
  <tr><th>Dev ID</th><th>Company</th><th>Contact</th><th>Country</th></tr>
  <!-- walk each of the dev nodes -->
  <xsl:for-each select="dev">
     <tr>
        <!-- build a table row consisting of the contents of the 
             id, company, contact, and country nodes -->
        <td><xsl:value-of select="id" /></td>
  	    <td><xsl:value-of select="company" /></td>  			
  	    <td><xsl:value-of select="contact" /></td>
        <td><xsl:value-of select="country" /></td>
     </tr>
  </xsl:for-each>
</table>
</body>
</html>
</xsl:template>
	
</xsl:stylesheet>

The following Perl script is used to load the XML data set and one of the XSLT stylesheets to produce the desired output. To run this script on your own Web server, you'll need to make sure that Perl is installed in addition to the XML::XSLT and Perl CGI modules.

#!/usr/local/bin/perl
#Tellme Studio Code Example 118 
#Copyright (C) 2000-2001 Tellme Networks, Inc. All Rights Reserved. 

#THIS CODE IS MADE AVAILABLE SOLELY ON AN "AS IS" BASIS, WITHOUT WARRANTY 
#OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, 
#WARRANTIES THAT THE CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A 
#PARTICULAR PURPOSE OR NON-INFRINGING. 

# XML::Sablotron is an open source XSLT processor
# available at http://www.gingerall.com/
# Search the Web for other XSLT processors.
use XML::Sablotron;
use CGI;
use strict;

my ($template) = "devs-";
my(@formats) = ("vxml2", "html"); # array of supported formats
my(@contenttypes) = ("text/xml", "text/html"); # array of corresponding content types

# use CGI module to get requested output format or default to VoiceXML
my $o = new CGI;
my($iFormat) = $o->param("format");
if (!defined($iFormat) || $iFormat < 0 || $iFormat >= scalar(@formats))
{
   $iFormat = 0;
}

# compose the path to the desired XSLT
$template .= ($formats[$iFormat] . ".xslt");

# load the template
my $oProcessor = new XML::Sablotron();

my @params = ();
my @args = ();
push @args, "data";
push @args, LoadData("devs.xml");
my($out_uri) = "arg:/result"; # bogus arg

# transform the data through the template
$oProcessor->RunProcessor($template, "arg:/data", $out_uri,
                   \@params, \@args);
my ($res) = $oProcessor->GetResultArg($out_uri);

# print the result of the transform to standard output
my ($ctype) = $contenttypes[$iFormat];
print <<EOF;
Content-Type: $ctype

$res
EOF

# load and return the contents of the specified document
sub LoadData
{
   my($path) = @_;

   $! = 0; # clear i/o errs
   open HFILE, $path;
   if ($! != 0)
   {
      return "";
   }

   my $eor = $/;
   undef $/;
   my $content = <HFILE>;
   close HFILE;
   $/ = $eor;

  return $content;
}

The following Active Server page is used to load the XML data set and one of the XSLT stylesheets to produce the desired output. To run this code, you'll need to save it to a server running Windows 2000 or later and Microsoft's XML parser version 3.0 or later.

<% @LANGUAGE="JScript" %>
<%
   /*
   Tellme Studio Code Example 118 
   Copyright (C) 2000-2001 Tellme Networks, Inc. All Rights Reserved. 

   THIS CODE IS MADE AVAILABLE SOLELY ON AN "AS IS" BASIS, WITHOUT WARRANTY 
   OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION,  
   WARRANTIES THAT THE CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A 
   PARTICULAR PURPOSE OR NON-INFRINGING. 
   */

   // compose name of desired XSLT
   var sTemplate = "devs-";
   var aFormats = ["vxml2", "html"];
   var aContentTypes = ["text/xml", "text/html"];
   var iFormat = Request("format");

   if (isNaN(iFormat) || iFormat < 0 || iFormat >= aFormats.length)
   {
      iFormat = 0;
   }   

   // set the HTTP content type
   Response.ContentType = aContentTypes[iFormat];

   // select the template
   sTemplate += (aFormats[iFormat] + ".xslt");

   // resolve the paths to the data and template
   var xmlpath = Server.MapPath("devs.xml");
   var xsltpath = Server.MapPath(sTemplate);

   // load the data and templates
   var oData = LoadXMLDoc(xmlpath);
   var oTemplate = LoadXMLDoc(xsltpath);
   if (oData && oTemplate)
   {
      // write the result of the transformation to the client
      Response.Write(oData.transformNode(oTemplate));
   }

   // simple routine to load the specified xml document
   function LoadXMLDoc(sPath)
   {
     var oDOM = Server.CreateObject("MSXML2.DOMDocument");
     oDOM.async = false;
     oDOM.load(sPath);
     if (oDOM.parseError.errorCode != 0)
     {
        Response.Write("<!-- " + oDOM.parseError.reason + "-->");
        return null;
     }
     else
     {
        return oDOM;
     }
   }   
%>

[24]7 Inc.| Terms of Service| Privacy Policy| General Disclaimers