Monday 11 February 2013

I'm Learning JavaScript!

I’ve finally learning about JavaScript after listening to the Google TechTalk, Doug Crockford: JavaScript: The Good Parts. Here are my first couple of test scripts. I’m using Rhino for runtime and JSLint (obviously) to check the code.

Through these code examples I learnt a lot, about the tools, the language and how to integrate it to do useful stuff. It is early days, but I can see JavaScript being a valuable instrument in my tool box!

Example 1 - Random Digits

Here is a simple command line script to produce random numbers from 0 to 9. The first two lines are pragmas passed to JSLint.


/*jslint indent: 4, maxlen: 80, rhino: true */
/*global java*/


// returns a semi-random digit between 0 and 9
function getRandomDigit() {
   
'use strict';
   
return Math.round(Math.random() * 9);}


// example using array
var digitName = (function () {
   
'use strict';
   
var names = ['zero', 'one', 'two', 'three', 'four',
       
'five', 'six', 'seven', 'eight', 'nine'];
   
return function (n) {
       
return names[n];
   
};
}());

// example using associative array
var getDigitName = (function () {
   
'use strict';
   
var names = {0 : 'zero', 1 : 'one', 2 : 'two',
       3 :
'three', 4 : 'four', 5 : 'five',
       6 :
'six', 7 : 'seven', 8 : 'eight',
       9 :
'nine' };
   
return function (n) {
       
return names[n];
   
};
}());

/*
* MAIN
*/
print(
'Printing 10 random digits ...');
var i;
for (i = 0; i < 10; i += 1) {
   
var rd = getRandomDigit();
   print(
'\t' + i + ') ' + rd + ' is ' + getDigitName(rd));
}


Here is an example execution of this script
$ rhino digit.js
Printing 10 random digits ...
0) 0 is zero
1) 6 is six
2) 2 is two
3) 1 is one
4) 3 is three
5) 2 is two
6) 1 is one
7) 6 is six
8) 8 is eight
9) 2 is two

Example 2 - Read an XML Document

Here I am using XPath to process an XML document.
Here is the test input file test.xml.

<?xml version="1.0" encoding="UTF-8"?>
<company>
 <employee id="003">frank</employee>
 <turnover>
   <year id="2011">100000</year>
   <year id="2012">140000</year>
   <year id="2013">200000</year>
 </turnover>
</company>

The script reads the document in three ways

  • query for a specific element meeting an attribute condition
  • show content of all nodes from a specific point
  • show the same, but this time including the attributes

/*jslint indent: 4, maxlen: 80, rhino: true */
/*global java, javax, org*/


// returns a semi-random digit between 0 and 9
function loadXml(fileName) {
   
'use strict';
   
var dbFactory = javax.xml.parsers.DocumentBuilderFactory.newInstance(),
       dBuilder = dbFactory.newDocumentBuilder(),
       xmlFile = java.io.File(fileName),
       xmlDoc = dBuilder.parse(xmlFile);
   xmlDoc.normalizeDocument();
   
return xmlDoc;}


// constructor
function DocumentNodes(xmlDoc) {
   
'use strict';
   
//var my = this;
   
this.xmlDoc = xmlDoc;
   
this.xpFactory = javax.xml.xpath.XPathFactory.newInstance();
   
this.xpath = this.xpFactory.newXPath();
   
// return node set of a specific type for a given expression
   
this.get = function (expression, type) {
       
var xpexpression = this.xpath.compile(expression);
       
return xpexpression.evaluate(this.xmlDoc, type);
   
};
}


/**************************************
* MAIN
**************************************/


// load document
var xmlDoc = loadXml('test.xml');

// read using xpath
var nodes = new DocumentNodes(xmlDoc);var results = nodes.get('/company/turnover/year[@id=2012]',
               javax.xml.xpath.XPathConstants.NODESET);


// show a specific year
var i;for (i = 0; i < results.getLength(); i += 1) {
   
var node = results.item(i).getFirstChild();
   print(
'Year 2012 has turnover of ' + node.getTextContent());
}


// show all years
results = nodes.get(
'/company/turnover/*',
           javax.xml.xpath.XPathConstants.NODESET);

for (i = 0; i < results.getLength(); i += 1) {
   print(results.item(i).getTextContent());

}


// show attributes and value for each year
for (i = 0; i < results.getLength(); i += 1) {
   
if (results.item(i).hasAttributes()) {
       print(results.item(i).getTextContent() +
' has attributes');
       
var attribs = results.item(i).getAttributes();
       
var j;
       
for (j = 0; j < attribs.getLength(); j += 1) {
           
var n = attribs.item(j);
           print(
'\t' + n.getNodeName() + ' = ' + n.getNodeValue());
       
}
   
}
}

And here is the scripts execution

$ rhino loadxml.js
Year 2012 has turnover of 140000
100000
140000
200000
100000 has attributes
id = 2011
140000 has attributes
id = 2012
200000 has attributes
id = 2013