I found an XML version of the I-Ching on the web, so I decided to whip up a little script to consult the book using XPath.

Check my home page for a demonstration.

Here is the perl code. Note that the actual script is over 90K as it has all the XML tacked on to the end. Also, the output is just a quick HTML hack with most of it hard-coded -- not very nice, but it works.

#!/usr/local/bin/perl -w require 5.005; my $VERSION = "1.0"; use strict; use XML::XPath; use CGI qw(header param); print header(-type=>'text/html'); my $template = "iching.template"; if (open TEMPLATE, $template) { while ( <TEMPLATE> ) { print; last if /<!-- ICHING -->/; } } if (my $question = param('askme')) { print "<p>You asked the oracle: &quot;$question&quot;</p>"; } my ($main_hex,$changed_hex,$moving_lines); # Toss three coins six times to get the lines of the # main hexagram and the changed hexagram. for (my $i=0; $i<6; $i++) { my $line = cast(); $main_hex .= $line; } sub cast { # Casts three coins. Heads worth three, tails worth two. # Returns between 6 and 9 representing one line of the # hexagram: # 6 - x - moving Yin # 7 ----- Yang # 8 -- -- Yin # 9 --o-- moving Yang my $line = 0; for (my $x=0; $x<3; $x++) { $line += int (rand(2)) + 2; } return $line; } # In the changed hexagram, moving Yin becomes Yang # and moving Yang becomes Yin. $changed_hex = ($moving_lines = $main_hex); $changed_hex =~ tr/6789/9966/; $moving_lines =~ tr/6789/1001/; $main_hex =~ tr/6789/6969/; # reverse moving_lines so we can use chop later $moving_lines = reverse $moving_lines; # Now we have the hexagrams, we need to consult the book. my $xml_data; while (<DATA>) { $xml_data .= $_ } my $parser = XML::XPath->new( xml=>$xml_data ); foreach my $pattern ($main_hex, $changed_hex) { my $nodeset = $parser->find( "/hexagrams/hexagram/pattern" ); foreach my $node ($nodeset->get_nodelist()) { if ( $parser->getNodeText($node) eq $pattern ) { my $hexagram = $node->getParentNode(); my %entry; foreach ('title','hexnum','above','below','judgement', 'image','extra') { $entry{$_} = $parser->getNodeText( $parser->find("./$_",$hexagram)); } print "<h2>$entry{hexnum} - $entry{title}</h2>"; print "<p>$entry{above} is above.<br />$entry{below} is below.</ +p>"; print "<p><em>Judgment:</em> $entry{judgement}</p>"; print "<p><em>Image:</em> $entry{image}</p>"; if (length($moving_lines) > 0) { my $c = 0; my @headings = ('', 'First', 'Second', 'Third', 'Fourth', 'Fifth', 'Top'); foreach my $l ($parser->find('./lines/line', $hexagram)->get_n +odelist) { $c++; if (chop $moving_lines) { print "<p><em>$headings[$c]:</em> ", $parser->getNodeText($l), '</p>'; } } } print "<p>$entry{extra}</p>" if $entry{extra}; last; } } } print while (<TEMPLATE>); exit;

</ajdelore>

Replies are listed 'Best First'.
Re: XML I-Ching
by gjb (Vicar) on Jul 08, 2003 at 19:23 UTC

    Ah, what a waste of time: you should know I-Ching doesn't work unless consulted using 49 yarrow stalks or 3 coins ;-)

    Best regards, -gjb-