The JSON standard is the good way to deliver data to a JavaScript application, because it is JavaScript. XML is a good way to publish data because it is a popular standard. If only there were some glue to stick these two good things together...

Turns out Perl is a good way to glue. So here's a little script that will run as a CGI to deliver an XML document as a JSON object. It does this on-the-fly using a XSL stylesheet and the XML-Sablotron module.

The trick is to set the URL of this script to be the source of your script tag.

<script src="http://example.com/cgi-bin/json.pl?foo=data.xml">
</script>

Notice the query-string stuck on the end of the URL. It has two parts: the first is the name of the JavaScript variable that will hold the JSON object, and the other is the XML document on the server that will be transformed. So, if things are working as they should, if we have a file named "data.xml" like the one below...


<books>
  <fiction>
    <title>Or All The Seas with Oysters</title>
  </fiction>
</books>

The following would be delivered by our perl script, which is just the same data transformed into a JavaScript object...

var foo = 
{   "#name": "books",
    "#text": "",
    "#children": [
    {   "#name": "fiction",
        "#text": "",
        "#children": [
        {   "#name": "title",
            "#text": "Or All The Seas with Oysters",
            "#children": [
            ]
        }
        ]
    }
    ]
}
;

And then we have the source for "json.pl" which uses Sablotron, but any XSLT software should work as well...

#!/usr/bin/perl

use strict;
use warnings;

use CGI;
use CGI::Carp qw(fatalsToBrowser);
use XML::Sablotron qw(:all);

my $cgi = new CGI;
my $sab = new XML::Sablotron();

my $data_name = shift @{[$cgi->param()]};
my $data_file = $cgi->param($data_name);

# I'll leave real security checks up to you...
$data_name =~ s/[^a-zA-Z0-9_]//g;
$data_file =~ s/\.\.//g;

$sab->runProcessor('rayfish.xsl', $data_file, 
                   'arg:/result', undef, undef);
my $result = $sab->getResultArg('arg:/result');

print $cgi->header('application/x-javascript');
unless($result) {
	print "alert('Error getting the XML data.');\n";
}
else { print "var $data_name = \n$result" }

If you're wondering what to do with that blob of JSON data you'll have to wait for the next entry on this, which will link to a JavaScript path language for querying JSON objects, but that is for another day.