Parsing XML in Sahi Scripts

Sahi uses Rhino as its javascript engine and Rhino has excellent support for handling XML.

Below is a script which reads and asserts XML nodes and attributes. The example has been picked from http://www.ibm.com/developerworks/webservices/library/ws-ajax1/ so that it is easy to experiment with the ibm examples in this script.

var xmlStr = '' +
'<people>' +
'   <person gender="male">' +
'      <name>Ant</name>' +
'      <hair>Shaggy</hair>' +
'      <eyes>Blue</eyes>' +
'      <height measure="metric">176</height>' +
'   </person>' +
'   <person gender="male">' +
'      <name>Paul</name>' +
'      <hair>Spiky</hair>' +
'      <eyes>Grey</eyes>' +
'      <height measure="metric">178</height>' +
'   </person>' +
'</people>';

xmlStr = xmlStr.replace(/<\?xml[^>]*\?>/, ""); // needed in some cases
var $x = new XML(xmlStr);
_assertEqual("Ant", $x.person[0].name.toString());
_assertEqual("Grey", $x.person[1].eyes.toString());

for each (var $p in $x.person){
    var $measure = $p.height.@measure.toString();
    _assert($measure == "metric");
    _assert($p.height > 170);
}


info
  1. All nodes that you access are of type xml. You will need to use toString() on them before you assert them.
  2. If your XML string starts with <?xml...?>, it may throw an error

    To fix it, do the following
    var xmlStr = xmlStr.replace(/<\?xml[^>]*\?>/, "");
    var $x = new XML(xmlStr);

Parsing XML containing namespaces

var $xmlStr = '' +
'<MyApp xmlns="http://sahi.co.in">' +
'   <Id xmlns="http://www.tytosoftware.com">123</Id>' +
'   <Messages>' +
'        <Welcome>Welcome1 to MyApp</Welcome>' +
'        <Farewell>Thank1 you for using MyApp</Farewell>' +
'    </Messages>' +
'</MyApp>' ;

var $x = new XML($xmlStr);

// Set the default namespace. All elements will be in this namespace
default xml namespace = "http://sahi.co.in";
var $welcome0 = $x..Welcome[0].toString();
_assertEqual("Welcome1 to MyApp", $welcome0);


// Specific namespace for id
var idns = new Namespace("http://www.tytosoftware.com");
// Access element using namespace::localName
var $id = $x.idns::Id.toString();
_assertEqual("123", $id);


For more details on e4x usage have a look at https://developer.mozilla.org/en-US/docs/E4X/Processing_XML_with_E4X.

There is a lot more that can be done with the XML object. Have a look at these links:
http://www.ibm.com/developerworks/webservices/library/ws-ajax1/
http://www.xml.com/pub/a/2007/11/28/introducing-e4x.html