The XML I-Ching Forecaster:
An exercise in XML document creation and the Tao of the DOM

By Peter A. Bromberg, Ph.D.

Peter Bromberg

I''ve been a student of Eastern philosophy and disciplines almost since getting out of high school.   For some reason, I've always been attracted to the Eastern mind and culture -- meditation, martial arts such as T'ai Chi (which I've studied) , and the I-Ching, or "Book of Changes". Natural order type things like fractal geometry and neural networks never cease to fascinate me. There is a certain discipline and order in the I-Ching as an ancient book of wisdom - some of which goes back 5,000 years - that is remarkably similar to the order we create from chaos when we use XML and XSLT - the idea that one thing (Yang) can be "Transformed" into another (Ying). You get the idea.



Recently I came upon some old text files I had saved of Hexagrams from the Book of Changes, and I thought it might be an interesting exercise to create some sort of web-based "oracle" that you could query and get out a divination from this ancient book. Since opposites tend to attract, in that it makes some sort of esoteric sense to use cutting - edge 21st century technology to display results from a 5,000 year old book, I thought "why not put this stuff into a database and create some sort of query front-end". The "Tao of the DOM", as it were....

For those who have not had an opportunity to study this useful text, the I-Ching, which is attributed to KIng Wên and Duke Chou, dates from a period long before the emergence of Taoism and Confucianism as separate entities. Confucius himself is the author of many of the Commentaries that can be found in the texts, but he came on the scene long after the original texts had been rendered. Most modern Chinese are very familiar with I-Ching, and hold it in high regard as a book of wisdom, to be respected and treated with the utmost care and reverence.

Interestingly enough (and without having consulted the Oracle for guidance) I found that each of my pages had text "headings" for the different sections that were remarkably uniform across each of the 64 Hexagrams in the I-Ching. Things like "Judgement", "image", etc. I soon realized that instead of converting the series of files into some sort of comma-delimited file for importation into SQL Server, it would actually be easier to use something like EditPlus to search and replace these common headings and simply convert everything into a well-formed XML Document. In that case, as long as the result wasn't too big, all I needed to do is load it into a DOMDocument object and I could search and transform to my heart's content.

Well, that's exactly what I did. In fact, it took about an hour. Now the big advantage of something like this is you might have an ASP based site that's hosted somewhere and you don't have access to a database. No problem, use text file, and create yourself an XML document as a "database". You could even load it into Application scope using the MSXML2.FreeThreadedDomDocument and have it accessible from every page on your site.

If you want to see the XML Document I put together (it's a VERY abbreviated, but reasonably accurate version of the Book of Change), check here.

I think at this point a word or two about how the I-Ching works is in order. I-Ching is comprised of 64 "hexagrams", each consisting of six Yang or Yin lines (----------- or -----    -----). For example, Hexagram 19, Lin ("Approach") looks like this:

ggg           ggg
ggg           ggg
ggg           ggg
ggg           ggg
ggggggggg
ggggggggg

The lines are numbered according to their type, a six being an "old" (moving) Yin line, seven being a "young" (static) Yin, eight is static Yang (--------------------), and nine being moving Yang. The oracle is consulted by casting a set of 49 yarrow stalks in a special sequence, or casting six throws of three Chinese coins, one for each line of the Hexagram, building from the bottom line up. As mathematician Robert R. Coveyou at the Oak Ridge National Laboratory once put it, "The generation of random numbers is too important to be left to chance.", so I opted to use the less strenuous coin toss method.

Once the Hexagram is constructed, the I Ching is consulted for that Hexagram, reading the Judgement, Image and any additional Commentary. Then the text related to the moving lines (if any) is consulted. Finally, if there are moving lines, these "Transform" into their opposite, yielding a new Hexagram which represents the final outcome of the divination, so this text is then studied. Now that we're all experts in Eastern wisdom, lets build a page to do this cool stuff.

First thing, I load the XML document:

<Script language=Javascript>
function throwIChing(){
var objXML, objXMLNodeList, sXPathQry, objNode, lngLength, newhex1, orig,newhex,srch;
var objXML = new ActiveXObject("MSXML2.DOMDocument.3.0");
objXML.async = false;
objXML.load("http://localhost/ICHING/ICHING.xml");

Then I call the Random function to get a Hexagram pattern:

var hexagram=castCoins();

Let's have a look at the castCoins() function:

function castCoins(){
var aryHex=new Array(5);
var line;
for(var i = 0;i<=5;i++)
{
// we need a random integer from 6 to 9 (6,7,8, or 9) to simulate the three coin toss
line=Math.round(Math.random()*3)+6;
aryHex[i]=line;
}
return aryHex;
}

OK? Then we set up our search pattern strings:

srch="";
orig="";
newhex="";
newhex1="";
for( var i=0;i<=5;i++){
orig+=hexagram[i].toString();
if(hexagram[i]==7){
hexagram[i]=6;
newhex1="9";
}
if(hexagram[i]==8){
hexagram[i]=9;
newhex1= "6";
}
if (newhex1 !=""){
newhex+=newhex1;
}
else{
newhex+=hexagram[i].toString();
}
srch+=hexagram[i].toString();
newhex1 = "";
} // end for

Basically what I'm doing above is converting the random pattern to all 6's or 9's because we need to perform an XPATH query to match a <pattern> element in each Hexagram node of the XML doc. That's how we find the Hexagram node that we cast. I also create a "newhex" pattern string to match the second Hexagram (if there is any). Next I simply start writing out the text of my report:

document.write("<CENTER><li>Actual Hexagram Line Pattern: " + orig + "<BR>");
document.write("<Li>First Hexagram Search Pattern: " + srch + "<BR>");
document.write("<Li>Next Hexagram Search Pattern: " + newhex + "</CENTER><BR>");
var test=getHexagramPattern(srch);
srch=test;
var objXMLNode = objXML.selectSingleNode("//hexagram[HexNum='" + srch + "']");
document.write( "<BASEFONT FACE=Verdana>");
document.write ("<Table cellspacing="2" cellpadding="2" border="0" align="center">");
document.write ("<Tr><td bgcolor=lightblue colspan="2" align="center">Hexagram " + objXMLNode.selectSingleNode("HexNum").text +": " + objXMLNode.selectSingleNode("Main/Title").text + "</td></tr>");
document.write( "<TR bgcolor=#ffcc66><TD>");
document.write( showLines(orig));
document.write ("</TD><TD><table><TR ><TD valign="top">");
document.write ("Upper Trigram: " + objXMLNode.selectSingleNode("Main/above").text + "<BR>");
document.write ("</td></TR>");
document.write ("<TR bgcolor=#ffcc66><TD valign="top">");
document.write ("Lower Trigram: " + objXMLNode.selectSingleNode("Main/below").text + "<BR>");
document.write ("</tr></table>");
document.write ("</TD></TR></table>");
document.write ("The Judgement: " + objXMLNode.selectSingleNode("judgement").text + "<BR>");
document.write ("<HR>");
document.write ("The Image: " + objXMLNode.selectSingleNode("image").text + "<BR>");

The selectSingleNode XPATH queries above grab all the text values of the items I need to display for this hexagram. The showLines() method simply creates a graphical display of what the Hexagram looks like. Next I write out the Commentary (but only if there is one, so I use a try-catch block):

// Suppress extra commentary display if there is none...
try {
var sExtra = objXMLNode.selectSingleNode("extra").text;
document.write("<HR>");
document.write( "Comment: " + sExtra + "<BR>");
}
catch(e){
}

Next I display any text related to the moving lines in the Hexagram (lines marked 6 or 9) with a little more complex XPATH query:

document.write( "<HR><CENTER>The Moving Line(s):</CENTER>");
var xmlLinesNodeList;
for(var q=0;q<=5;q++){
if (orig.substr(q,1)=="6" || orig.substr(q,1)=="9"){
xmlLinesNodeList=objXML.selectSingleNode("//hexagram[HexNum='" + srch + "']/lines/Line["+q +"]");
var LineComment = xmlLinesNodeList.text;
document.write(LineComment + "<BR>");
} // end if
} // end for

Then I write out the stuff for the next hexagram the same way as the first. My Hexagram "pattern list" is in an array in the getHexagramPattern() function:

function getHexagramPattern(srch){
var hgmAry= new Array("999999","666666","966696","696669", etc.etc.);
for(var i = 0;i<=63;i++){
if(hgmAry[i]==srch){
getHexagramPattern = i +1;
break;
}
}
return getHexagramPattern;
}

Finally, in the HTML body of my page I have a DIV whose innerHTML property is written to for the display, and a button to fire the function:

<HTML>
<HEAD>
<BODY>
<div align="center"><input type=button value="Consult the I-Ching" onClick="throwIChing();"></div><BR>
<div id=display align="center"></div>

And that's the XML I-CHING! I hope you enjoy it and that you enjoy Sublime Success with no blame. If you'd like to try it out online, CLICK HERE!

Download the code that accompanies this article.

Peter Bromberg is an independent consultant specializing in distributed .NET solutionsa Senior Programmer / Analyst at in Orlando and a co-developer of the NullSkull.com developer website. He can be reached at info@eggheadcafe.com