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>


In reply to XML I-Ching by ajdelore

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.