|
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.
|