The work for releases 1.0, 1.2 and 1.2.1 was sponsored by the National
Library of Australia, whose help we gratefully acknowledge.
+1.12 TO BE RELEASED
+ - rewrite the CQL lexer to better conform to CQL spec (e.g retain escapes for wildcards, etc)
+ - add jUnit test cases
+
1.11 Tue 5 Mar 2013 13:38:18 CET
- Fix problem with parsing unquoted terms that begin with a '.'
- Fix problem with parsing unquoted terms that contain a '@'
VERSION The version-number of this distribution
Changes History of releases
LGPL-2.1 The GNU lesser GPL (see below)
- Makefile, Build Files to control compilation.
- src Source-code for the CQL-Java library
- lib The compiled library file, "cql-java.jar"
- bin Simple shell-scripts to invoke the test-harnesses
- docs Documentation automatically generated by "javadoc"
- test Various testing and sanity-checking frameworks
+ pom.xml Maven project file to control compilation.
+ src Source-code for the CQL-Java library and tests
+ target The compiled library file, "cql-java.jar" and javadoc
+ bin Simple shell-scripts to invoke CQL programs (parser/lexer/generator)
+ util Various testing and sanity-checking Perl scripts
etc Other files: PQF indexes, generator properties, etc.
"Installation" of this package would consist of putting the bin
-directory on your PATH and lib/cql-java.jar on your CLASSPATH.
+directory on your PATH and target/cql-java.jar on your CLASSPATH.
SYNOPSIS
DESCRIPTION
-----------
-See the automatically generated class documentation in the "doc"
+See the automatically generated class documentation in the "target"
subdirectory.
AUTHOR
------
-Code and documentation by Mike Taylor, Index Data <mike@indexdata.com>
- http://indexdata.com
+Original code and documentation by Mike Taylor, Index Data <mike@indexdata.com>
+At present maintained by Jakub Skoczen, Index Data <jakub@indexdata.dk>
+
+ http://www.indexdata.com/cql-java
http://zing.z3950.org/cql
+
Please email me with bug-reports, wishlist items, patches, deployment
stories and, of course, large cash donations.
Adam Dickmeiss's CQL compiler, written in C.
Rob Sanderson's CQL compiler, written in Python.
+Jakub Skoczen's CQL-js compiler, written in JavaScript http://git.indexdata.com/?p=cql-js.git
All the other free CQL compilers everyone's going to write :-)
The "Changes" file, including the "Still to do" section.
case TT_EOF:
return "EOF";
case TT_WORD:
- return "word: " + val;
+ return "word: '" + val + "'";
case '"':
return "string: \"" + val + "\"";
case TT_LE:
+++ /dev/null
-
-all: ../../target/cql-java-1.8.jar
- PATH=$(PATH):../../bin CLASSPATH=../../target/cql-java-1.8.jar ./mkrandom 100
-
-../../target/cql-java-1.8.jar:
- cd ../../ && mvn package
-
-clean:
- @echo "Nothing to do to 'make clean'"
-
+++ /dev/null
-
-In this directory, we test the integrity of the CQL-Java tools as
-follows:
-
-* Generate a random tree with CQLGenerate
-* Take a copy
-* Canonicalise it with CQLparser -c.
-* Compare the before-and-after versions.
-
-Since the CQLGenerate output is in canonical form anyway, the
-before-and-after versions should be identical. This process exercises
-the comprehensiveness and bullet-proofing of the parser, as well as
-the accuracy of the rendering.
-
+++ /dev/null
-#!/usr/bin/perl -w
-
-
-use strict;
-
-my $n = 1;
-if (@ARGV > 1) {
- print STDERR "Usage: $0 [<number-of-trees>]\n";
- exit 1;
-} elsif (@ARGV == 1) {
- $n = $ARGV[0];
-}
-
-my $nok = 0;
-for (my $i = 0; $i < $n; $i++) {
- print $i+1, " of $n -- ";
- my $query=`CQLGenerator ../../etc/generate.properties`;
- print $query;
- my $canon=`CQLParser -c '$query'`;
- if ($canon eq $query) {
- $nok++;
- } else {
- print "ERROR: canonicalised query differs from original\n";
- }
-}
-
-print "Passed $nok/$n -- ", int(100*$nok/$n), "%\n";
+++ /dev/null
-
-XMLCANONICALISER = cat
-# Change this to "./xmlpp.pl" if you want to check for equivalence
-
-test: sections/01/01.cql sections/01/01.xcql
- ./runtests ../../bin/CQLParser $(XMLCANONICALISER)
-
-test-adam: sections/01/01.cql sections/01/01.xcql
- ./runtests ../../../srw/cql/cql2xcql $(XMLCANONICALISER)
-
-test-rob: sections/01/01.cql sections/01/01.xcql
- ./runtests ../../../rob/CQLParser.py $(XMLCANONICALISER)
-
-sections/01/01.cql: mktests queries.raw
- ./mktests queries.raw
-
-sections/01/01.xcql: mkanswers
- ./mkanswers ../../bin/CQLParser
-# OR ./mkanswers ../../../srw/cql/cql2xcql
-# OR ./mkanswers ../../../rob/CQLParser.py
-# Depending on which parser you want to use as your reference
-
-clean:
- @echo "Nothing to do to 'make clean'"
-
-distclean:
- find sections . -name '*.cql' -exec rm \{\} \;
-
-refclean:
- find sections . -name '*.xcql' -exec rm \{\} \;
+++ /dev/null
-
-If you just don't want to think about it
-----------------------------------------
-
-Just use "make" to run regression tests.
-
-
-CQL-Java's regression-testing framework
----------------------------------------
-
-"queries.raw" is the file of test queries as provided by Rob.
-"mktests" parses the raw file into sections and individual queries
-"sections" is the top-level directory created by that program.
- "01", "02" etc. represent the sections within the raw file
- "01/name", "02/name", etc. contain the names of the sections.
- "01/01.cql", "01/02.cql" etc. are the CQL queries themselves.
-"mkanswers" uses a trusted CQL compiler to generate corresponding XCQL.
- "01/01.xcql", "01/02.xcql" etc. are the compiled XCQL queries.
-
-Apart from the CQL files, all of the files described to this point are
-included in the distribution, with the "trusted" XCQL output produced
-by my own compiler, and used for regression testing of new versions.
-The CQL files are re-created from "queries.raw" as required. But
-you're welcome to "make refclean" and rebuild it with mkanswers, to
-contain the trusted compiler output of your choice.
-
-"runtests" compares the output of a nominated CQL compiler with
-existing XCQL files. Most often, you'll use this to compare the
-results of your own build of CQL-Java with those of my build. I'll
-use it to test new versions, and people who've written other compilers
-can use it to test their code. (The code of "runtests" and
-"mkanswers" is worryingly similar: they should probably be the same
-program invoked with different command-line arguments.)
-
-"Makefile" controls the building of all this. You'll need to edit it
-if you want to use different compilers and suchlike from what's
-written into it, so it may be easier to run the tests by hand -- but
-it's a useful reference for the kinds of commands you might need,
-anyway. In general, "make" will run the regression tests, creating
-whatever CQL and/or XCQL files it needs; if you do "make refclean"
-first, then the next "make" will rebuild the reference results.
-
-So, for example, if you think Rob Sanderson's parser, CQLParser.py, is
-reliable, and you want to test my parser, CQL-Java's CQLParser class,
-against its results, do this:
-
- make refclean
- ./mktests queries.raw
- ./mkanswers CQLParser.py
- ./runtests ../../bin/CQLParser ./xmlpp.pl
-
-The second argument to ./runtests is the name of a program to use to
-normalise XML, so that the trusted output and the output being tested
-can be compared for equivalence rather than just for being
-byte-identical. (If you want to test for byte-identical XCQL, then
-use "cat" as the second argument.) xmlpp.pl is a fine XML
-pretty-printer from DecisionSoft, found at
- http://software.decisionsoft.com/tools.html
-
-"showtest" can be used to run a single test showing more details of
-what goes wrong, if anything. You don't need it as part of the
-regression test, but it's useful when debugging.
-
-Finally, "runcanon" checks that each of the queries when compiled and
-decompiled back to CQL (i.e. canonicalised) remains identical when
-recompiled and redecompiled.
-
-
-Appendix: queries that should fail
-----------------------------------
-
-The following queries are included in Rob's master list, in a final
-section called "Invalid searches [should error]". They are all
-expected to fail in various ways. I've taken them out of
-"queries.raw" because it's uninteresting, not to mention rather
-disturbing, to watch compilers fail. More important, I think, to
-demonstrate correct behaviour for the known-to-work queries.
-
->
-===
-cat or
-index any
-index any/wrong term
-a prox/wrong b
-()
-(a
-index any fish)
-(cat any dog or ())
-title = ("illegal parentheses")
-"quoted" any "illegal quotes"
-> illegal="urn:missingQuery"
-"fish" and > illegal="urn:invalidPrefixLocation" "chips"
+++ /dev/null
-#!/usr/bin/perl -w
-
-
-use IO::File;
-use strict;
-
-$ENV{CLASSPATH} .= ":../../lib/cql-java.jar";
-
-if (@ARGV != 1) {
- print STDERR "Usage: $0 <trusted-CQL-compiler>\n";
- exit(1);
-}
-my $compiler = $ARGV[0];
-
-while (<sections/*>) {
- my $sdir = $_;
- s@sections/@@;
- next if /^CVS$/ || /^10$/; # I _can't_ get CVS to stop extracting "10"
- print "answering section $_ - ", read_file("$sdir/name"), "\n";
-
- while (<$sdir/*.cql>) {
- my $qfile = $_;
- s@sections/([0-9]+/.*)\.cql@$1@;
- my $query = read_file($qfile);
- my $afile = $qfile;
- $afile =~ s/\.cql$/.xcql/;
- print " wrote $_ - $query\n";
- my $fh = new IO::File("| $compiler > $afile")
- or die "can't run compiler '$compiler': $!";
- print $fh $query;
- $fh->close();
- }
-}
-
-sub read_file {
- my($name) = @_;
-
- my $fh = new IO::File("<$name")
- or die "can't read '$name': $!";
- my $contents = join('', <$fh>);
- $fh->close();
- return $contents;
-}
+++ /dev/null
-#!/usr/bin/perl -w
-
-
-use IO::File;
-use strict;
-
-maybe_mkdir("sections");
-my $section = 0;
-my $dir;
-my $query;
-
-while (<>) {
- chomp();
- s/[ \t]+$//;
- next if /^$/;
-
- if (s/^#[ \t]*//) {
- $section++;
- $query = 0;
- $dir = "sections/" . substr("0$section", -2);
- maybe_mkdir($dir);
- write_file("$dir/name", $_);
- print "created section $section ($dir) - $_\n";
- next;
- }
-
- die "query before first section header"
- if !defined $dir;
-
- $query++;
- my $filename = $dir . "/" . substr("0$query", -2) . ".cql";
- write_file($filename, $_);
- $filename =~ s@sections/(.*)\.cql@$1@;
- print " added $filename - $_\n";
-}
-
-sub write_file {
- my($name, $contents) = @_;
-
- my $fh = new IO::File(">$name")
- or die "can't create '$name': $!";
- $fh->print($contents);
- $fh->close();
-}
-
-sub maybe_mkdir {
- my($dir) = shift();
- if (mkdir $dir) {
- return;
- }
- if ($! =~ /exists/i) {
- return;
- }
- die "can't create directory '$dir': $!";
-}
+++ /dev/null
-
-# Simple
-
-cat
-"cat"
-comp.os.linux
-xml:element
-"<xml:element>"
-"="
-"prox/distance<3/unit=word"
-("cat")
-((dog))
-all
-prox
-
-# Index Relation Term
-
-title = "fish"
-title exact fish
-title any fish
-title all fish
-title > 9
-title >= 23
-dc.title any "fish chips"
-dc.title any/stem fish
-dc.fish all/stem/fuzzy "fish chips"
-(title any frog)
-((dc.title any/stem "frog pond"))
-dc.title any "fish frog chicken"
-dc.title =/rel.algorithm=CORI squid
-author any/f.foo/b.bar>1 "sanderson taylor"
-numberOfLegs <= 4
-numberOfLegs <> 4
-title == jaws
-
-# Simple Boolean
-
-cat or dog
-cat and fish
-cat not frog
-(cat not frog)
-"cat" not "fish food"
-xml and "prox///"
-fred and any
-((fred or all))
-a or b and c not d
-
-# I/R/T plus Boolean
-
-bath.author any fish and dc.title all "cat dog"
-(title any/stem "fish dog" or and)
-
-# Prox
-
-cat prox hat
-cat prox/distance=3/unit=word/ordered hat
-cat prox/distance<3 hat
-"fish food" prox/unit=sentence and
-title all "chips frog" prox/distance<=5 exact
-(dc.author == "jones" prox/distance>5/unit=element title >= "smith")
-((cat prox hat))
-a and/rel.SumOfScores b
-a and/rel.algorithm=CORI b
-
-# Special Characters
-
-(cat^)
-"cat"
-"^cat says \"fish\""
-"cat*fish"
-cat?dog
-(("^cat*fishdog\"horse?"))
-
-# Nesting Parentheses
-
-(((cat or dog) or horse) and frog)
-(cat and dog) or (horse and frog)
-(cat and (horse or frog)) and chips
-
-# Prefix Maps
-
-> foo="http://www.loc.gov/zing/cql/dc-indexes/" dc.title="fish"
-> "http://www.loc.gov/zing/cql/dc-indexes/" title="fish"
-> foo="http://www.loc.gov/zing/cql/dc-indexes" > ccg = "http://srw.o-r-g.org/cql/indexSets/ccg/" foo.title="fish" and ccg.force=3
-
-# Lame Searches
-
-any or all:stem and all contains any prox proxfuzzy
-(((((((((any)))))))))
-""
-> any > any = exact any > any
-sortby sortby sortby
-sortby sortby sortby sortby sortby
-
-# Sorting
-
-kernighan sortby title
-kernighan and ritchie sortby title
-dc.creator=kernighan sortby dc.title
-dc.creator=kernighan sortby numberOfLegs/cql.number
-dc.creator=kernighan sortby dc.title/sort.respectCase
-dc.creator=kernighan sortby dc.title/sort.respectCase/sort.descending
-dc.creator=kernighan sortby dc.date dc.title
-dc.creator=kernighan sortby dc.date/sort.missingOmit
-dc.creator=kernighan sortby dc.date/sort.missingValue=1970
->dc="http://deepcustard.org/1.0" blah sortby dc.custardDepth
->ns1="http://uri1" >ns2="http://uri2" whatever sortby ns1.key/a/b/c=1 ns2.key2
-(>dc=x b=c) sortby d
-b=(>dc=x c) sortby d
-(>dc=x c1 and c2) sortby d
->dc="http://deepcustard.org" (>dc="http://dublincore.org" dc.title=jaws) sortby dc.custardDepth
->dc="http://deepcustard.org" (fish or >dc="http://dublincore.org" dc.title=jaws) sortby dc.custardDepth
+++ /dev/null
-#!/usr/bin/perl -w
-
-#
-# Tests that all sample queries can be rendered into idempotent
-# canoncial form.
-
-use IO::File;
-use strict;
-
-$ENV{CLASSPATH} .= ":../../lib/cql-java.jar";
-
-my($ntests, $ncorrect) = (0, 0);
-
-while (<sections/*>) {
- my $sdir = $_;
- s@sections/@@;
- next if /^CVS$/ || /^10$/;
- print "testing section $_ - ", read_file("$sdir/name"), "\n";
-
- while (<$sdir/*.cql>) {
- my $qfile = $_;
- s@sections/([0-9]+/.*)\.cql@$1@;
- my $query = read_file($qfile);
- my $canonical = `CQLParser -c '$query'`;
- chomp($canonical);
- my $maybe = `CQLParser -c '$canonical'`;
- chomp($maybe);
- print "$query // $canonical ";
- $ntests++;
- if ($maybe eq $canonical) {
- $ncorrect++;
- print " OK\n";
- } else {
- print "### $maybe\n";
- }
- }
-}
-
-print sprintf("%d of %d passed: %d%%\n",
- $ncorrect, $ntests, (100 * $ncorrect) / $ntests);
-
-sub read_file {
- my($name) = @_;
-
- $name = "<$name" if $name !~ /\|$/;
- my $fh = new IO::File("$name")
- or die "can't read '$name': $!";
- my $contents = join('', <$fh>);
- $fh->close();
- return $contents;
-}
+++ /dev/null
-#!/usr/bin/perl -w
-
-
-use IO::File;
-use strict;
-
-$ENV{CLASSPATH} .= ":../../src/main/java";
-$ENV{CLASSPATH} .= ":../../lib/cql-java.jar";
-
-if (@ARGV != 2) {
- print STDERR "Usage: $0 <CQL-compiler> <XML-normaliser>\n";
- exit(1);
-}
-my $compiler = $ARGV[0];
-my $norman = $ARGV[1]; # name of XML normaliser program
-my($ntests, $ncorrect) = (0, 0);
-
-while (<sections/*>) {
- my $sdir = $_;
- s@sections/@@;
- next if /^CVS$/;
- print "testing section $_ - ", read_file("$sdir/name"), "\n";
-
- while (<$sdir/*.cql>) {
- my $qfile = $_;
- s@sections/([0-9]+/.*)\.cql@$1@;
- my $query = read_file($qfile);
- my $afile = $qfile;
- $afile =~ s/\.cql$/.xcql/;
- print " query $_ - $query ";
- $ntests++;
- my $correct = read_file("$norman < $afile |");
- my $tested = read_file("$compiler < $qfile | $norman |");
- if (!$tested) {
- print "\n *** test compiler exited non-zero\n";
- } elsif ($tested eq $correct) {
- print "OK\n";
- $ncorrect++;
- } else {
- print "\n *** XCQL output differs from $afile\n";
- print "=== tested ===\n$tested";
- print "=== end ===\n";
- }
- }
-}
-
-print sprintf("%d of %d passed: %d%%\n",
- $ncorrect, $ntests, (100 * $ncorrect) / $ntests);
-
-sub read_file {
- my($name) = @_;
-
- $name = "<$name" if $name !~ /\|$/;
- my $fh = new IO::File("$name")
- or die "can't read '$name': $!";
- my $contents = join('', <$fh>);
- $fh->close();
- return $contents;
-}
+++ /dev/null
-name
-*.cql
+++ /dev/null
-<searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>cat</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>cat</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>comp.os.linux</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>xml:element</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term><xml:element></term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>=</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>prox/distance<3/unit=word</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>cat</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>dog</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>all</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>prox</term>
-</searchClause>
+++ /dev/null
-name
-*.cql
+++ /dev/null
-<searchClause>
- <index>title</index>
- <relation>
- <value>=</value>
- </relation>
- <term>fish</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>title</index>
- <relation>
- <value>exact</value>
- </relation>
- <term>fish</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>title</index>
- <relation>
- <value>any</value>
- </relation>
- <term>fish</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>title</index>
- <relation>
- <value>all</value>
- </relation>
- <term>fish</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>title</index>
- <relation>
- <value>></value>
- </relation>
- <term>9</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>title</index>
- <relation>
- <value>>=</value>
- </relation>
- <term>23</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>dc.title</index>
- <relation>
- <value>any</value>
- </relation>
- <term>fish chips</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>dc.title</index>
- <relation>
- <value>any</value>
- <modifiers>
- <modifier>
- <type>stem</type>
- </modifier>
- </modifiers>
- </relation>
- <term>fish</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>dc.fish</index>
- <relation>
- <value>all</value>
- <modifiers>
- <modifier>
- <type>stem</type>
- </modifier>
- <modifier>
- <type>fuzzy</type>
- </modifier>
- </modifiers>
- </relation>
- <term>fish chips</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>title</index>
- <relation>
- <value>any</value>
- </relation>
- <term>frog</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>dc.title</index>
- <relation>
- <value>any</value>
- <modifiers>
- <modifier>
- <type>stem</type>
- </modifier>
- </modifiers>
- </relation>
- <term>frog pond</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>dc.title</index>
- <relation>
- <value>any</value>
- </relation>
- <term>fish frog chicken</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>dc.title</index>
- <relation>
- <value>=</value>
- <modifiers>
- <modifier>
- <type>rel.algorithm</type>
- <comparison>=</comparison>
- <value>CORI</value>
- </modifier>
- </modifiers>
- </relation>
- <term>squid</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>author</index>
- <relation>
- <value>any</value>
- <modifiers>
- <modifier>
- <type>f.foo</type>
- </modifier>
- <modifier>
- <type>b.bar</type>
- <comparison>></comparison>
- <value>1</value>
- </modifier>
- </modifiers>
- </relation>
- <term>sanderson taylor</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>numberOfLegs</index>
- <relation>
- <value><=</value>
- </relation>
- <term>4</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>numberOfLegs</index>
- <relation>
- <value><></value>
- </relation>
- <term>4</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>title</index>
- <relation>
- <value>==</value>
- </relation>
- <term>jaws</term>
-</searchClause>
+++ /dev/null
-name
-*.cql
+++ /dev/null
-<triple>
- <boolean>
- <value>or</value>
- </boolean>
- <leftOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>cat</term>
- </searchClause>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>dog</term>
- </searchClause>
- </rightOperand>
-</triple>
+++ /dev/null
-<triple>
- <boolean>
- <value>and</value>
- </boolean>
- <leftOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>cat</term>
- </searchClause>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>fish</term>
- </searchClause>
- </rightOperand>
-</triple>
+++ /dev/null
-<triple>
- <boolean>
- <value>not</value>
- </boolean>
- <leftOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>cat</term>
- </searchClause>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>frog</term>
- </searchClause>
- </rightOperand>
-</triple>
+++ /dev/null
-<triple>
- <boolean>
- <value>not</value>
- </boolean>
- <leftOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>cat</term>
- </searchClause>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>frog</term>
- </searchClause>
- </rightOperand>
-</triple>
+++ /dev/null
-<triple>
- <boolean>
- <value>not</value>
- </boolean>
- <leftOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>cat</term>
- </searchClause>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>fish food</term>
- </searchClause>
- </rightOperand>
-</triple>
+++ /dev/null
-<triple>
- <boolean>
- <value>and</value>
- </boolean>
- <leftOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>xml</term>
- </searchClause>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>prox///</term>
- </searchClause>
- </rightOperand>
-</triple>
+++ /dev/null
-<triple>
- <boolean>
- <value>and</value>
- </boolean>
- <leftOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>fred</term>
- </searchClause>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>any</term>
- </searchClause>
- </rightOperand>
-</triple>
+++ /dev/null
-<triple>
- <boolean>
- <value>or</value>
- </boolean>
- <leftOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>fred</term>
- </searchClause>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>all</term>
- </searchClause>
- </rightOperand>
-</triple>
+++ /dev/null
-<triple>
- <boolean>
- <value>not</value>
- </boolean>
- <leftOperand>
- <triple>
- <boolean>
- <value>and</value>
- </boolean>
- <leftOperand>
- <triple>
- <boolean>
- <value>or</value>
- </boolean>
- <leftOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>a</term>
- </searchClause>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>b</term>
- </searchClause>
- </rightOperand>
- </triple>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>c</term>
- </searchClause>
- </rightOperand>
- </triple>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>d</term>
- </searchClause>
- </rightOperand>
-</triple>
+++ /dev/null
-name
-*.cql
+++ /dev/null
-<triple>
- <boolean>
- <value>and</value>
- </boolean>
- <leftOperand>
- <searchClause>
- <index>bath.author</index>
- <relation>
- <value>any</value>
- </relation>
- <term>fish</term>
- </searchClause>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>dc.title</index>
- <relation>
- <value>all</value>
- </relation>
- <term>cat dog</term>
- </searchClause>
- </rightOperand>
-</triple>
+++ /dev/null
-<triple>
- <boolean>
- <value>or</value>
- </boolean>
- <leftOperand>
- <searchClause>
- <index>title</index>
- <relation>
- <value>any</value>
- <modifiers>
- <modifier>
- <type>stem</type>
- </modifier>
- </modifiers>
- </relation>
- <term>fish dog</term>
- </searchClause>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>and</term>
- </searchClause>
- </rightOperand>
-</triple>
+++ /dev/null
-name
-*.cql
+++ /dev/null
-<triple>
- <boolean>
- <value>prox</value>
- </boolean>
- <leftOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>cat</term>
- </searchClause>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>hat</term>
- </searchClause>
- </rightOperand>
-</triple>
+++ /dev/null
-<triple>
- <boolean>
- <value>prox</value>
- <modifiers>
- <modifier>
- <type>distance</type>
- <comparison>=</comparison>
- <value>3</value>
- </modifier>
- <modifier>
- <type>unit</type>
- <comparison>=</comparison>
- <value>word</value>
- </modifier>
- <modifier>
- <type>ordered</type>
- </modifier>
- </modifiers>
- </boolean>
- <leftOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>cat</term>
- </searchClause>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>hat</term>
- </searchClause>
- </rightOperand>
-</triple>
+++ /dev/null
-<triple>
- <boolean>
- <value>prox</value>
- <modifiers>
- <modifier>
- <type>distance</type>
- <comparison><</comparison>
- <value>3</value>
- </modifier>
- </modifiers>
- </boolean>
- <leftOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>cat</term>
- </searchClause>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>hat</term>
- </searchClause>
- </rightOperand>
-</triple>
+++ /dev/null
-<triple>
- <boolean>
- <value>prox</value>
- <modifiers>
- <modifier>
- <type>unit</type>
- <comparison>=</comparison>
- <value>sentence</value>
- </modifier>
- </modifiers>
- </boolean>
- <leftOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>fish food</term>
- </searchClause>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>and</term>
- </searchClause>
- </rightOperand>
-</triple>
+++ /dev/null
-<triple>
- <boolean>
- <value>prox</value>
- <modifiers>
- <modifier>
- <type>distance</type>
- <comparison><=</comparison>
- <value>5</value>
- </modifier>
- </modifiers>
- </boolean>
- <leftOperand>
- <searchClause>
- <index>title</index>
- <relation>
- <value>all</value>
- </relation>
- <term>chips frog</term>
- </searchClause>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>exact</term>
- </searchClause>
- </rightOperand>
-</triple>
+++ /dev/null
-<triple>
- <boolean>
- <value>prox</value>
- <modifiers>
- <modifier>
- <type>distance</type>
- <comparison>></comparison>
- <value>5</value>
- </modifier>
- <modifier>
- <type>unit</type>
- <comparison>=</comparison>
- <value>element</value>
- </modifier>
- </modifiers>
- </boolean>
- <leftOperand>
- <searchClause>
- <index>dc.author</index>
- <relation>
- <value>==</value>
- </relation>
- <term>jones</term>
- </searchClause>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>title</index>
- <relation>
- <value>>=</value>
- </relation>
- <term>smith</term>
- </searchClause>
- </rightOperand>
-</triple>
+++ /dev/null
-<triple>
- <boolean>
- <value>prox</value>
- </boolean>
- <leftOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>cat</term>
- </searchClause>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>hat</term>
- </searchClause>
- </rightOperand>
-</triple>
+++ /dev/null
-<triple>
- <boolean>
- <value>and</value>
- <modifiers>
- <modifier>
- <type>rel.sumofscores</type>
- </modifier>
- </modifiers>
- </boolean>
- <leftOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>a</term>
- </searchClause>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>b</term>
- </searchClause>
- </rightOperand>
-</triple>
+++ /dev/null
-<triple>
- <boolean>
- <value>and</value>
- <modifiers>
- <modifier>
- <type>rel.algorithm</type>
- <comparison>=</comparison>
- <value>CORI</value>
- </modifier>
- </modifiers>
- </boolean>
- <leftOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>a</term>
- </searchClause>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>b</term>
- </searchClause>
- </rightOperand>
-</triple>
+++ /dev/null
-name
-*.cql
+++ /dev/null
-<searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>cat^</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>cat</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>^cat says "fish"</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>cat*fish</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>cat?dog</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>^cat*fishdog"horse?</term>
-</searchClause>
+++ /dev/null
-name
-*.cql
+++ /dev/null
-<triple>
- <boolean>
- <value>and</value>
- </boolean>
- <leftOperand>
- <triple>
- <boolean>
- <value>or</value>
- </boolean>
- <leftOperand>
- <triple>
- <boolean>
- <value>or</value>
- </boolean>
- <leftOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>cat</term>
- </searchClause>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>dog</term>
- </searchClause>
- </rightOperand>
- </triple>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>horse</term>
- </searchClause>
- </rightOperand>
- </triple>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>frog</term>
- </searchClause>
- </rightOperand>
-</triple>
+++ /dev/null
-<triple>
- <boolean>
- <value>or</value>
- </boolean>
- <leftOperand>
- <triple>
- <boolean>
- <value>and</value>
- </boolean>
- <leftOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>cat</term>
- </searchClause>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>dog</term>
- </searchClause>
- </rightOperand>
- </triple>
- </leftOperand>
- <rightOperand>
- <triple>
- <boolean>
- <value>and</value>
- </boolean>
- <leftOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>horse</term>
- </searchClause>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>frog</term>
- </searchClause>
- </rightOperand>
- </triple>
- </rightOperand>
-</triple>
+++ /dev/null
-<triple>
- <boolean>
- <value>and</value>
- </boolean>
- <leftOperand>
- <triple>
- <boolean>
- <value>and</value>
- </boolean>
- <leftOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>cat</term>
- </searchClause>
- </leftOperand>
- <rightOperand>
- <triple>
- <boolean>
- <value>or</value>
- </boolean>
- <leftOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>horse</term>
- </searchClause>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>frog</term>
- </searchClause>
- </rightOperand>
- </triple>
- </rightOperand>
- </triple>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>chips</term>
- </searchClause>
- </rightOperand>
-</triple>
+++ /dev/null
-name
-*.cql
+++ /dev/null
-<searchClause>
- <prefixes>
- <prefix>
- <name>foo</name>
- <identifier>http://www.loc.gov/zing/cql/dc-indexes/</identifier>
- </prefix>
- </prefixes>
- <index>dc.title</index>
- <relation>
- <value>=</value>
- </relation>
- <term>fish</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <prefixes>
- <prefix>
- <identifier>http://www.loc.gov/zing/cql/dc-indexes/</identifier>
- </prefix>
- </prefixes>
- <index>title</index>
- <relation>
- <value>=</value>
- </relation>
- <term>fish</term>
-</searchClause>
+++ /dev/null
-<triple>
- <prefixes>
- <prefix>
- <name>foo</name>
- <identifier>http://www.loc.gov/zing/cql/dc-indexes</identifier>
- </prefix>
- <prefix>
- <name>ccg</name>
- <identifier>http://srw.o-r-g.org/cql/indexSets/ccg/</identifier>
- </prefix>
- </prefixes>
- <boolean>
- <value>and</value>
- </boolean>
- <leftOperand>
- <searchClause>
- <index>foo.title</index>
- <relation>
- <value>=</value>
- </relation>
- <term>fish</term>
- </searchClause>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>ccg.force</index>
- <relation>
- <value>=</value>
- </relation>
- <term>3</term>
- </searchClause>
- </rightOperand>
-</triple>
+++ /dev/null
-name
-*.cql
+++ /dev/null
-<triple>
- <boolean>
- <value>and</value>
- </boolean>
- <leftOperand>
- <triple>
- <boolean>
- <value>or</value>
- </boolean>
- <leftOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>any</term>
- </searchClause>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>all:stem</term>
- </searchClause>
- </rightOperand>
- </triple>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>all contains</index>
- <relation>
- <value>any</value>
- </relation>
- <term>prox proxfuzzy</term>
- </searchClause>
- </rightOperand>
-</triple>
+++ /dev/null
-<searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>any</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term></term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <prefixes>
- <prefix>
- <identifier>any</identifier>
- </prefix>
- <prefix>
- <name>any</name>
- <identifier>exact</identifier>
- </prefix>
- </prefixes>
- <index>any</index>
- <relation>
- <value>></value>
- </relation>
- <term>any</term>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>sortby</term>
- <sortKeys>
- <key>
- <index>sortby</index>
- </key>
- </sortKeys>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>sortby</term>
- <sortKeys>
- <key>
- <index>sortby</index>
- </key>
- <key>
- <index>sortby</index>
- </key>
- <key>
- <index>sortby</index>
- </key>
- </sortKeys>
-</searchClause>
+++ /dev/null
-name
-*.cql
+++ /dev/null
-<searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>kernighan</term>
- <sortKeys>
- <key>
- <index>title</index>
- </key>
- </sortKeys>
-</searchClause>
+++ /dev/null
-<triple>
- <boolean>
- <value>and</value>
- </boolean>
- <leftOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>kernighan</term>
- </searchClause>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>ritchie</term>
- </searchClause>
- </rightOperand>
- <sortKeys>
- <key>
- <index>title</index>
- </key>
- </sortKeys>
-</triple>
+++ /dev/null
-<searchClause>
- <index>dc.creator</index>
- <relation>
- <value>=</value>
- </relation>
- <term>kernighan</term>
- <sortKeys>
- <key>
- <index>dc.title</index>
- </key>
- </sortKeys>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>dc.creator</index>
- <relation>
- <value>=</value>
- </relation>
- <term>kernighan</term>
- <sortKeys>
- <key>
- <index>numberOfLegs</index>
- <modifiers>
- <modifier>
- <type>cql.number</type>
- </modifier>
- </modifiers>
- </key>
- </sortKeys>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>dc.creator</index>
- <relation>
- <value>=</value>
- </relation>
- <term>kernighan</term>
- <sortKeys>
- <key>
- <index>dc.title</index>
- <modifiers>
- <modifier>
- <type>sort.respectcase</type>
- </modifier>
- </modifiers>
- </key>
- </sortKeys>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>dc.creator</index>
- <relation>
- <value>=</value>
- </relation>
- <term>kernighan</term>
- <sortKeys>
- <key>
- <index>dc.title</index>
- <modifiers>
- <modifier>
- <type>sort.respectcase</type>
- </modifier>
- <modifier>
- <type>sort.descending</type>
- </modifier>
- </modifiers>
- </key>
- </sortKeys>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>dc.creator</index>
- <relation>
- <value>=</value>
- </relation>
- <term>kernighan</term>
- <sortKeys>
- <key>
- <index>dc.date</index>
- </key>
- <key>
- <index>dc.title</index>
- </key>
- </sortKeys>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>dc.creator</index>
- <relation>
- <value>=</value>
- </relation>
- <term>kernighan</term>
- <sortKeys>
- <key>
- <index>dc.date</index>
- <modifiers>
- <modifier>
- <type>sort.missingomit</type>
- </modifier>
- </modifiers>
- </key>
- </sortKeys>
-</searchClause>
+++ /dev/null
-<searchClause>
- <index>dc.creator</index>
- <relation>
- <value>=</value>
- </relation>
- <term>kernighan</term>
- <sortKeys>
- <key>
- <index>dc.date</index>
- <modifiers>
- <modifier>
- <type>sort.missingvalue</type>
- <comparison>=</comparison>
- <value>1970</value>
- </modifier>
- </modifiers>
- </key>
- </sortKeys>
-</searchClause>
+++ /dev/null
-<searchClause>
- <prefixes>
- <prefix>
- <name>dc</name>
- <identifier>http://deepcustard.org/1.0</identifier>
- </prefix>
- </prefixes>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>blah</term>
- <sortKeys>
- <key>
- <index>dc.custardDepth</index>
- </key>
- </sortKeys>
-</searchClause>
+++ /dev/null
-<searchClause>
- <prefixes>
- <prefix>
- <name>ns1</name>
- <identifier>http://uri1</identifier>
- </prefix>
- <prefix>
- <name>ns2</name>
- <identifier>http://uri2</identifier>
- </prefix>
- </prefixes>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>whatever</term>
- <sortKeys>
- <key>
- <index>ns1.key</index>
- <modifiers>
- <modifier>
- <type>a</type>
- </modifier>
- <modifier>
- <type>b</type>
- </modifier>
- <modifier>
- <type>c</type>
- <comparison>=</comparison>
- <value>1</value>
- </modifier>
- </modifiers>
- </key>
- <key>
- <index>ns2.key2</index>
- </key>
- </sortKeys>
-</searchClause>
+++ /dev/null
-<searchClause>
- <prefixes>
- <prefix>
- <name>dc</name>
- <identifier>x</identifier>
- </prefix>
- </prefixes>
- <index>b</index>
- <relation>
- <value>=</value>
- </relation>
- <term>c</term>
- <sortKeys>
- <key>
- <index>d</index>
- </key>
- </sortKeys>
-</searchClause>
+++ /dev/null
-<searchClause>
- <prefixes>
- <prefix>
- <name>dc</name>
- <identifier>x</identifier>
- </prefix>
- </prefixes>
- <index>b</index>
- <relation>
- <value>=</value>
- </relation>
- <term>c</term>
- <sortKeys>
- <key>
- <index>d</index>
- </key>
- </sortKeys>
-</searchClause>
+++ /dev/null
-<triple>
- <prefixes>
- <prefix>
- <name>dc</name>
- <identifier>x</identifier>
- </prefix>
- </prefixes>
- <boolean>
- <value>and</value>
- </boolean>
- <leftOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>c1</term>
- </searchClause>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>c2</term>
- </searchClause>
- </rightOperand>
- <sortKeys>
- <key>
- <index>d</index>
- </key>
- </sortKeys>
-</triple>
+++ /dev/null
-<searchClause>
- <prefixes>
- <prefix>
- <name>dc</name>
- <identifier>http://deepcustard.org</identifier>
- </prefix>
- <prefix>
- <name>dc</name>
- <identifier>http://dublincore.org</identifier>
- </prefix>
- </prefixes>
- <index>dc.title</index>
- <relation>
- <value>=</value>
- </relation>
- <term>jaws</term>
- <sortKeys>
- <key>
- <index>dc.custardDepth</index>
- </key>
- </sortKeys>
-</searchClause>
+++ /dev/null
-<triple>
- <prefixes>
- <prefix>
- <name>dc</name>
- <identifier>http://deepcustard.org</identifier>
- </prefix>
- </prefixes>
- <boolean>
- <value>or</value>
- </boolean>
- <leftOperand>
- <searchClause>
- <index>cql.serverChoice</index>
- <relation>
- <value>=</value>
- </relation>
- <term>fish</term>
- </searchClause>
- </leftOperand>
- <rightOperand>
- <searchClause>
- <prefixes>
- <prefix>
- <name>dc</name>
- <identifier>http://dublincore.org</identifier>
- </prefix>
- </prefixes>
- <index>dc.title</index>
- <relation>
- <value>=</value>
- </relation>
- <term>jaws</term>
- </searchClause>
- </rightOperand>
- <sortKeys>
- <key>
- <index>dc.custardDepth</index>
- </key>
- </sortKeys>
-</triple>
+++ /dev/null
-#!/bin/sh
-
-
-if [ $# != 1 ]; then
- echo "Usage: $0 <test-name>" >&2
- echo " e.g. $0 01/02" >&2
- exit 1
-fi
-
-### Warning: nasty hard-coded choices
-( echo "=== Adam ==="
- ../../../srw/cql/cql2xcql < sections/$1.cql ) > /tmp/adam
-( echo "=== Mike ==="
- ../../bin/CQLParser < sections/$1.cql ) > /tmp/mike
-sdiff -w 80 /tmp/adam /tmp/mike
+++ /dev/null
-#!/usr/bin/perl -w
-
-#
-# Copyright (c) 2002, DecisionSoft Limited All rights reserved.
-# Please see:
-# http://software.decisionsoft.com/license.html
-# for more information.
-#
-
-# $Revision: 1.2 $
-#
-# xmlpp: XML pretty printing
-#
-
-# For custom attribute sorting create an attributeOrdering.txt file that
-# lists each attributes separated by a newline in the order you would like
-# them to be sorted separated by a newline. Then use the -s option.
-
-use FileHandle;
-use Fcntl;
-use Getopt::Std;
-
-use vars qw($opt_h $opt_H $opt_s $opt_z $opt_t $opt_e $opt_S $opt_c $opt_n $opt_l);
-
-my $indent=0;
-my $textContent='';
-my $lastTag=undef;
-my $output;
-my $inAnnotation = 0;
-
-
-if (!getopts('nzhHsteScl:') or $opt_h) {
- usage();
-}
-
-my $indentSize = $opt_l || 2;
-
-if ($opt_s){
-
-# expect to find attributeOrdering.txt file in same directory
-# as xmlpp is being run from
-
- my $scriptDir = $0;
- if ($scriptDir =~ m#/#){
- $scriptDir =~ s#/[^/]+$##;
- }
- else{
- $scriptDir =".";
- }
-
- # get attribute ordering from external file
- if (open(SORTLIST, "<$scriptDir/attributeOrdering.txt")) {
- @sortlist = <SORTLIST>;
- chomp @sortlist;
- close (SORTLIST);
- @specialSort = grep(/^\w+/, @sortlist);
- }
- else {
- print STDERR "Could not open $scriptDir/attributeOrdering.txt: $!\nWARNING attribute sorting will only be alphabetic\n\n";
- }
-}
-
-
-# set line separator to ">" speeding up parsing of XML files
-# with no line breaks
-
-$/ = ">";
-
-
-my $sortAttributes = $opt_s;
-my $newLineComments = $opt_c;
-my $splitAttributes = $opt_t;
-my $schemaHackMode = $opt_S;
-my $normaliseWhiteSpace = $opt_n;
-
-my $filename = $ARGV[0];
-if ($opt_z && (!$filename or $filename eq '-')) {
- print STDERR "Error: I can't edit STDIN in place.\n";
- usage();
-}
-
-if (!$opt_z && scalar(@ARGV) > 1) {
- print STDERR "Warning: Multiple files specified without -z option\n";
-}
-
-my $fh;
-
-my $stdin;
-
-if (!$filename or $filename eq '-') {
- $fh=*STDIN;
- $stdin=1;
-} else {
- $fh = open_next_file() or exit(1);
- $stdin=0;
-}
-
-do {
- $indent=0;
- $textContent='';
- $lastTag=undef;
- $output = '';
- my $re_name = "(?:[A-Za-z0-9_:][A-Za-z0-9_:.-]*)";
- my $re_attr = "(?:'[^']*'|\"[^\"]*\")";
- my $input;
-
- while ($input .= <$fh>) {
- while ($input) {
- if ($input =~ s/^<($re_name)((?:\s+$re_name\s*=\s*$re_attr)*\s*)(\/?)>(.*)$/$4/s ) {
- my %attr;
- my ($name,$attr,$selfclose) = ($1,$2,$3);
- while ($attr =~ m/($re_name)\s*=\s*($re_attr)/gs) {
- my ($name,$value) = ($1,$2);
- $value =~ s/^["'](.*)["']$/$1/s;
- $attr{$name} = $value;
- }
- if ($opt_e) {
- parseStart($name, 0, %attr);
- if ($selfclose) { parseEnd($name) }
- } else {
- parseStart($name, $selfclose, %attr);
- }
- } elsif ($input =~ s/^<\/($re_name)\s*>(.*)$/$2/s) {
- parseEnd($1);
- } elsif ($input =~ s/^<!--(.*?)-->(.*)$/$2/s) {
- parseComment($1);
- } elsif ($input =~ s/^([^<]+)(.*)$/$2/s) {
- parseDefault($1);
- } elsif ($input =~ s/^(<\?[^>]*\?>)(.*)$/$2/s) {
- parsePI("$1\n");
- } elsif ($input =~ s/^(<\!DOCTYPE[^\[>]*(\[[^\]]*\])?[^>]*>)(.*)$/$3/s) {
- parseDoctype("$1");
- } else {
- last;
- }
- }
- if (eof($fh)) {
- last;
- }
- }
-
-
- if ($input) {
- $input =~ m/([^\n]+)/gs;
- print STDERR "WARNING: junk remaining on input: $1\n";
- }
- $fh->close();
-
- if (!$opt_z) {
- if(!$opt_H){
- print "$output\n"
- } else {
- print html_escape($output)."\n"
- }
- } else {
- if ($input) {
- print STDERR "Not overwriting file\n";
- } else {
- open FOUT,"> $filename" or die "Cannot overwrite file: $!";
- if(!$opt_H){
- print FOUT "$output\n"
- } else {
- print FOUT html_escape($output)."\n"
- }
- close FOUT
- }
- }
-} while (
- !$stdin && $opt_z && ($fh = open_next_file(\$filename))
- );
-
-
-
-sub parseStart {
- my $s = shift;
- my $selfclose = shift;
- my %attr = @_;
-
- $textContent =~ s/\s+$//;
- printContent($textContent);
-
- if($inAnnotation) {
- return;
- }
-
- if($schemaHackMode and $s =~ m/(^|:)annotation$/) {
- $inAnnotation = 1;
- $textContent = '';
- $lastTag = 1;
- return;
- }
- if (length($output)) {
- $output .= "\n";
- }
-
- $output .= " " x ($indent * $indentSize);
- $output .= "<$s";
- my @k = keys %attr;
-
- if ($sortAttributes && (scalar(@k) > 1) ){
-
- my @alphaSorted;
- my @needSpecialSort;
- my @final;
- my $isSpecial;
-
- # sort attributes alphabetically (default ordering)
- @alphaSorted = sort @k;
-
- # read through sorted list, if attribute doesn't have specified
- # sort order, push it onto the end of the final array (this maintains
- # alphabetic order). Else create a list that has attributes needing
- # special ordering.
- foreach $attribute (@alphaSorted){
- $isSpecial = 0;
- foreach $sortAttrib (@specialSort){
- if ($attribute eq $sortAttrib){
- push @needSpecialSort, $attribute;
- $isSpecial = 1;
- }
- }
- if (!$isSpecial){
- push @final, $attribute;
- }
- }
-
- # now read through the specialSort list backwards looking for
- # any match in the needSpecialSort list. Unshift this onto the
- # front of the final array to maintain proper order.
- foreach my $attribute (reverse @specialSort){
- foreach (@needSpecialSort){
- if ($attribute eq $_){
- unshift @final, $attribute;
- }
- }
- }
-
- @k = @final;
- }
-
- foreach my $attr (@k) {
- #
- # Remove (min|max)Occurs = 1 if schemaHackMode
- #
- if ($schemaHackMode and $attr =~ m/^(minOccurs|maxOccurs)$/ and $attr{$attr} eq "1") {
- next;
- }
-
- if ($splitAttributes) {
- $output .= "\n"." " x ($indent * $indentSize) ." ";
- }
- if ($attr{$attr} =~ /'/) {
- $output .= " $attr=\"$attr{$attr}\"";
- } else {
- $output .= " $attr='$attr{$attr}'";
- }
- }
- if ($splitAttributes and @k) {
- $output .= "\n"." " x ($indent * $indentSize);
- }
- if ($selfclose) {
- $output .= " />";
- $lastTag = 0;
- } else {
- $output .= ">";
- $indent++;
- $lastTag = 1;
- }
- $textContent = '';
-}
-
-sub parseEnd {
- my $s = shift;
-
- if($inAnnotation) {
- if($s =~ m/(^|:)annotation$/) {
- $inAnnotation = 0;
- }
- return;
- }
-
- if($normaliseWhiteSpace) {
- $textContent =~ s/^\s*(.*?)\s*$/$1/;
- }
- $indent--;
- printContent($textContent);
- if ($lastTag == 0) {
- $output .= "\n";
- $output .= " " x ($indent * $indentSize);
- }
- $output .= "</$s>";
- $textContent = '';
- $lastTag = 0;
-}
-
-sub parseDefault {
- my $s = shift;
- if($inAnnotation) { return }
- $textContent .= "$s";
-}
-
-sub parsePI {
- my $s = shift;
- $output .= "$s";
-}
-
-sub parseDoctype {
- my $s = shift;
- if ($s =~ /^([^\[]*\[)([^\]]*)(\].*)$/ms) {
- $start = $1;
- $DTD = $2;
- $finish = $3;
- $DTD =~ s/\</\n \</msg;
- $output .= "$start$DTD\n$finish\n";
- } else {
- $output .= "$s";
- }
-}
-
-sub parseComment {
- my $s = shift;
- if($inAnnotation) { return }
- printContent($textContent,1);
- if ($s =~ /([^\<]*)(<.*>)(.*)/ms) {
- $start = $1;
- $xml = $2;
- $finish = $3;
- $xml =~ s/\</\n\</msg;
- $xml =~ s/(\n\s*\n?)+/\n/msg;
- $xml =~ s/^\s*//msg;
- $xml =~ s/\s*$//msg;
- $s = "$start\n$xml\n$finish";
- }
- $s =~ s/\n\s*$/\n /msg;
- if ($newLineComments) {
- $output .= "\n<!--$s-->\n";
- } else {
- $output .= "<!--$s-->";
- }
- $textContent='';
-}
-
-sub printContent {
- my $s = shift;
- my $printLF = shift;
- my ($LF,$ret) = ("","");
-
- if ($s =~ m/\n\s*$/) {
- $LF = "\n";
- }
- if ($s =~ m/^[\s\n]*$/) {
- $ret = undef;
- } else {
- $output .= "$s";
- $ret = 1;
- }
- if ($printLF) {
- $output .= $LF;
- }
-}
-
-
-sub html_escape {
- my $s = shift;
- $s =~ s/&/&/gsm;
- $s =~ s/</</gsm;
- $s =~ s/>/>/gsm;
- return $s;
-}
-
-sub open_next_file {
- my $filename = shift;
- $$filename = shift @ARGV;
- while ($$filename and ! -f $$filename) {
- print STDERR "WARNING: Could not find file: $$filename\n";
- $$filename = shift @ARGV;
- }
- if(!$$filename) {
- return undef;
- }
- my $fh = new FileHandle;
- $fh->open("< $$filename") or die "Can't open $$filename: $!";
- return $fh;
-}
-
-sub usage {
- print STDERR <<EOF;
-usage: $0 [ options ] [ file.xml ... ]
-
-options:
- -h display this help message
- -H escape characters (useful for further processing)
- -t split attributes, one per line (useful for diff)
- -s sort attributes (useful for diff)
- -z in place edit (zap)
- -e expand self closing tags (useful for diff)
- -S schema hack mode (used by xmldiff)
- -c place comments on new line.
- -n normalise whitespace (remove leading and trailing whitespace from nodes
- with text content.
- -l <num> Indent each level by <num> spaces [default: 2]
-EOF
- exit 1;
-}
-
--- /dev/null
+
+all: ../../target/cql-java-1.8.jar
+ PATH=$(PATH):../../bin CLASSPATH=../../target/cql-java-1.8.jar ./mkrandom 100
+
+../../target/cql-java-1.8.jar:
+ cd ../../ && mvn package
+
+clean:
+ @echo "Nothing to do to 'make clean'"
+
--- /dev/null
+
+In this directory, we test the integrity of the CQL-Java tools as
+follows:
+
+* Generate a random tree with CQLGenerate
+* Take a copy
+* Canonicalise it with CQLparser -c.
+* Compare the before-and-after versions.
+
+Since the CQLGenerate output is in canonical form anyway, the
+before-and-after versions should be identical. This process exercises
+the comprehensiveness and bullet-proofing of the parser, as well as
+the accuracy of the rendering.
+
--- /dev/null
+#!/usr/bin/perl -w
+
+
+use strict;
+
+my $n = 1;
+if (@ARGV > 1) {
+ print STDERR "Usage: $0 [<number-of-trees>]\n";
+ exit 1;
+} elsif (@ARGV == 1) {
+ $n = $ARGV[0];
+}
+
+my $nok = 0;
+for (my $i = 0; $i < $n; $i++) {
+ print $i+1, " of $n -- ";
+ my $query=`CQLGenerator ../../etc/generate.properties`;
+ print $query;
+ my $canon=`CQLParser -c '$query'`;
+ if ($canon eq $query) {
+ $nok++;
+ } else {
+ print "ERROR: canonicalised query differs from original\n";
+ }
+}
+
+print "Passed $nok/$n -- ", int(100*$nok/$n), "%\n";
--- /dev/null
+
+XMLCANONICALISER = cat
+# Change this to "./xmlpp.pl" if you want to check for equivalence
+
+test: sections/01/01.cql sections/01/01.xcql
+ ./runtests ../../bin/CQLParser $(XMLCANONICALISER)
+
+test-adam: sections/01/01.cql sections/01/01.xcql
+ ./runtests ../../../srw/cql/cql2xcql $(XMLCANONICALISER)
+
+test-rob: sections/01/01.cql sections/01/01.xcql
+ ./runtests ../../../rob/CQLParser.py $(XMLCANONICALISER)
+
+sections/01/01.cql: mktests queries.raw
+ ./mktests queries.raw
+
+sections/01/01.xcql: mkanswers
+ ./mkanswers ../../bin/CQLParser
+# OR ./mkanswers ../../../srw/cql/cql2xcql
+# OR ./mkanswers ../../../rob/CQLParser.py
+# Depending on which parser you want to use as your reference
+
+clean:
+ @echo "Nothing to do to 'make clean'"
+
+distclean:
+ find sections . -name '*.cql' -exec rm \{\} \;
+
+refclean:
+ find sections . -name '*.xcql' -exec rm \{\} \;
--- /dev/null
+
+If you just don't want to think about it
+----------------------------------------
+
+Just use "make" to run regression tests.
+
+
+CQL-Java's regression-testing framework
+---------------------------------------
+
+"queries.raw" is the file of test queries as provided by Rob.
+"mktests" parses the raw file into sections and individual queries
+"sections" is the top-level directory created by that program.
+ "01", "02" etc. represent the sections within the raw file
+ "01/name", "02/name", etc. contain the names of the sections.
+ "01/01.cql", "01/02.cql" etc. are the CQL queries themselves.
+"mkanswers" uses a trusted CQL compiler to generate corresponding XCQL.
+ "01/01.xcql", "01/02.xcql" etc. are the compiled XCQL queries.
+
+Apart from the CQL files, all of the files described to this point are
+included in the distribution, with the "trusted" XCQL output produced
+by my own compiler, and used for regression testing of new versions.
+The CQL files are re-created from "queries.raw" as required. But
+you're welcome to "make refclean" and rebuild it with mkanswers, to
+contain the trusted compiler output of your choice.
+
+"runtests" compares the output of a nominated CQL compiler with
+existing XCQL files. Most often, you'll use this to compare the
+results of your own build of CQL-Java with those of my build. I'll
+use it to test new versions, and people who've written other compilers
+can use it to test their code. (The code of "runtests" and
+"mkanswers" is worryingly similar: they should probably be the same
+program invoked with different command-line arguments.)
+
+"Makefile" controls the building of all this. You'll need to edit it
+if you want to use different compilers and suchlike from what's
+written into it, so it may be easier to run the tests by hand -- but
+it's a useful reference for the kinds of commands you might need,
+anyway. In general, "make" will run the regression tests, creating
+whatever CQL and/or XCQL files it needs; if you do "make refclean"
+first, then the next "make" will rebuild the reference results.
+
+So, for example, if you think Rob Sanderson's parser, CQLParser.py, is
+reliable, and you want to test my parser, CQL-Java's CQLParser class,
+against its results, do this:
+
+ make refclean
+ ./mktests queries.raw
+ ./mkanswers CQLParser.py
+ ./runtests ../../bin/CQLParser ./xmlpp.pl
+
+The second argument to ./runtests is the name of a program to use to
+normalise XML, so that the trusted output and the output being tested
+can be compared for equivalence rather than just for being
+byte-identical. (If you want to test for byte-identical XCQL, then
+use "cat" as the second argument.) xmlpp.pl is a fine XML
+pretty-printer from DecisionSoft, found at
+ http://software.decisionsoft.com/tools.html
+
+"showtest" can be used to run a single test showing more details of
+what goes wrong, if anything. You don't need it as part of the
+regression test, but it's useful when debugging.
+
+Finally, "runcanon" checks that each of the queries when compiled and
+decompiled back to CQL (i.e. canonicalised) remains identical when
+recompiled and redecompiled.
+
+
+Appendix: queries that should fail
+----------------------------------
+
+The following queries are included in Rob's master list, in a final
+section called "Invalid searches [should error]". They are all
+expected to fail in various ways. I've taken them out of
+"queries.raw" because it's uninteresting, not to mention rather
+disturbing, to watch compilers fail. More important, I think, to
+demonstrate correct behaviour for the known-to-work queries.
+
+>
+===
+cat or
+index any
+index any/wrong term
+a prox/wrong b
+()
+(a
+index any fish)
+(cat any dog or ())
+title = ("illegal parentheses")
+"quoted" any "illegal quotes"
+> illegal="urn:missingQuery"
+"fish" and > illegal="urn:invalidPrefixLocation" "chips"
--- /dev/null
+#!/usr/bin/perl -w
+
+
+use IO::File;
+use strict;
+
+$ENV{CLASSPATH} .= ":../../lib/cql-java.jar";
+
+if (@ARGV != 1) {
+ print STDERR "Usage: $0 <trusted-CQL-compiler>\n";
+ exit(1);
+}
+my $compiler = $ARGV[0];
+
+while (<sections/*>) {
+ my $sdir = $_;
+ s@sections/@@;
+ next if /^CVS$/ || /^10$/; # I _can't_ get CVS to stop extracting "10"
+ print "answering section $_ - ", read_file("$sdir/name"), "\n";
+
+ while (<$sdir/*.cql>) {
+ my $qfile = $_;
+ s@sections/([0-9]+/.*)\.cql@$1@;
+ my $query = read_file($qfile);
+ my $afile = $qfile;
+ $afile =~ s/\.cql$/.xcql/;
+ print " wrote $_ - $query\n";
+ my $fh = new IO::File("| $compiler > $afile")
+ or die "can't run compiler '$compiler': $!";
+ print $fh $query;
+ $fh->close();
+ }
+}
+
+sub read_file {
+ my($name) = @_;
+
+ my $fh = new IO::File("<$name")
+ or die "can't read '$name': $!";
+ my $contents = join('', <$fh>);
+ $fh->close();
+ return $contents;
+}
--- /dev/null
+#!/usr/bin/perl -w
+
+
+use IO::File;
+use strict;
+
+maybe_mkdir("sections");
+my $section = 0;
+my $dir;
+my $query;
+
+while (<>) {
+ chomp();
+ s/[ \t]+$//;
+ next if /^$/;
+
+ if (s/^#[ \t]*//) {
+ $section++;
+ $query = 0;
+ $dir = "sections/" . substr("0$section", -2);
+ maybe_mkdir($dir);
+ write_file("$dir/name", $_);
+ print "created section $section ($dir) - $_\n";
+ next;
+ }
+
+ die "query before first section header"
+ if !defined $dir;
+
+ $query++;
+ my $filename = $dir . "/" . substr("0$query", -2) . ".cql";
+ write_file($filename, $_);
+ $filename =~ s@sections/(.*)\.cql@$1@;
+ print " added $filename - $_\n";
+}
+
+sub write_file {
+ my($name, $contents) = @_;
+
+ my $fh = new IO::File(">$name")
+ or die "can't create '$name': $!";
+ $fh->print($contents);
+ $fh->close();
+}
+
+sub maybe_mkdir {
+ my($dir) = shift();
+ if (mkdir $dir) {
+ return;
+ }
+ if ($! =~ /exists/i) {
+ return;
+ }
+ die "can't create directory '$dir': $!";
+}
--- /dev/null
+
+# Simple
+
+cat
+"cat"
+comp.os.linux
+xml:element
+"<xml:element>"
+"="
+"prox/distance<3/unit=word"
+("cat")
+((dog))
+all
+prox
+
+# Index Relation Term
+
+title = "fish"
+title exact fish
+title any fish
+title all fish
+title > 9
+title >= 23
+dc.title any "fish chips"
+dc.title any/stem fish
+dc.fish all/stem/fuzzy "fish chips"
+(title any frog)
+((dc.title any/stem "frog pond"))
+dc.title any "fish frog chicken"
+dc.title =/rel.algorithm=CORI squid
+author any/f.foo/b.bar>1 "sanderson taylor"
+numberOfLegs <= 4
+numberOfLegs <> 4
+title == jaws
+
+# Simple Boolean
+
+cat or dog
+cat and fish
+cat not frog
+(cat not frog)
+"cat" not "fish food"
+xml and "prox///"
+fred and any
+((fred or all))
+a or b and c not d
+
+# I/R/T plus Boolean
+
+bath.author any fish and dc.title all "cat dog"
+(title any/stem "fish dog" or and)
+
+# Prox
+
+cat prox hat
+cat prox/distance=3/unit=word/ordered hat
+cat prox/distance<3 hat
+"fish food" prox/unit=sentence and
+title all "chips frog" prox/distance<=5 exact
+(dc.author == "jones" prox/distance>5/unit=element title >= "smith")
+((cat prox hat))
+a and/rel.SumOfScores b
+a and/rel.algorithm=CORI b
+
+# Special Characters
+
+(cat^)
+"cat"
+"^cat says \"fish\""
+"cat*fish"
+cat?dog
+(("^cat*fishdog\"horse?"))
+
+# Nesting Parentheses
+
+(((cat or dog) or horse) and frog)
+(cat and dog) or (horse and frog)
+(cat and (horse or frog)) and chips
+
+# Prefix Maps
+
+> foo="http://www.loc.gov/zing/cql/dc-indexes/" dc.title="fish"
+> "http://www.loc.gov/zing/cql/dc-indexes/" title="fish"
+> foo="http://www.loc.gov/zing/cql/dc-indexes" > ccg = "http://srw.o-r-g.org/cql/indexSets/ccg/" foo.title="fish" and ccg.force=3
+
+# Lame Searches
+
+any or all:stem and all contains any prox proxfuzzy
+(((((((((any)))))))))
+""
+> any > any = exact any > any
+sortby sortby sortby
+sortby sortby sortby sortby sortby
+
+# Sorting
+
+kernighan sortby title
+kernighan and ritchie sortby title
+dc.creator=kernighan sortby dc.title
+dc.creator=kernighan sortby numberOfLegs/cql.number
+dc.creator=kernighan sortby dc.title/sort.respectCase
+dc.creator=kernighan sortby dc.title/sort.respectCase/sort.descending
+dc.creator=kernighan sortby dc.date dc.title
+dc.creator=kernighan sortby dc.date/sort.missingOmit
+dc.creator=kernighan sortby dc.date/sort.missingValue=1970
+>dc="http://deepcustard.org/1.0" blah sortby dc.custardDepth
+>ns1="http://uri1" >ns2="http://uri2" whatever sortby ns1.key/a/b/c=1 ns2.key2
+(>dc=x b=c) sortby d
+b=(>dc=x c) sortby d
+(>dc=x c1 and c2) sortby d
+>dc="http://deepcustard.org" (>dc="http://dublincore.org" dc.title=jaws) sortby dc.custardDepth
+>dc="http://deepcustard.org" (fish or >dc="http://dublincore.org" dc.title=jaws) sortby dc.custardDepth
--- /dev/null
+#!/usr/bin/perl -w
+
+#
+# Tests that all sample queries can be rendered into idempotent
+# canoncial form.
+
+use IO::File;
+use strict;
+
+$ENV{CLASSPATH} .= ":../../lib/cql-java.jar";
+
+my($ntests, $ncorrect) = (0, 0);
+
+while (<sections/*>) {
+ my $sdir = $_;
+ s@sections/@@;
+ next if /^CVS$/ || /^10$/;
+ print "testing section $_ - ", read_file("$sdir/name"), "\n";
+
+ while (<$sdir/*.cql>) {
+ my $qfile = $_;
+ s@sections/([0-9]+/.*)\.cql@$1@;
+ my $query = read_file($qfile);
+ my $canonical = `CQLParser -c '$query'`;
+ chomp($canonical);
+ my $maybe = `CQLParser -c '$canonical'`;
+ chomp($maybe);
+ print "$query // $canonical ";
+ $ntests++;
+ if ($maybe eq $canonical) {
+ $ncorrect++;
+ print " OK\n";
+ } else {
+ print "### $maybe\n";
+ }
+ }
+}
+
+print sprintf("%d of %d passed: %d%%\n",
+ $ncorrect, $ntests, (100 * $ncorrect) / $ntests);
+
+sub read_file {
+ my($name) = @_;
+
+ $name = "<$name" if $name !~ /\|$/;
+ my $fh = new IO::File("$name")
+ or die "can't read '$name': $!";
+ my $contents = join('', <$fh>);
+ $fh->close();
+ return $contents;
+}
--- /dev/null
+#!/usr/bin/perl -w
+
+
+use IO::File;
+use strict;
+
+$ENV{CLASSPATH} .= ":../../src/main/java";
+$ENV{CLASSPATH} .= ":../../lib/cql-java.jar";
+
+if (@ARGV != 2) {
+ print STDERR "Usage: $0 <CQL-compiler> <XML-normaliser>\n";
+ exit(1);
+}
+my $compiler = $ARGV[0];
+my $norman = $ARGV[1]; # name of XML normaliser program
+my($ntests, $ncorrect) = (0, 0);
+
+while (<sections/*>) {
+ my $sdir = $_;
+ s@sections/@@;
+ next if /^CVS$/;
+ print "testing section $_ - ", read_file("$sdir/name"), "\n";
+
+ while (<$sdir/*.cql>) {
+ my $qfile = $_;
+ s@sections/([0-9]+/.*)\.cql@$1@;
+ my $query = read_file($qfile);
+ my $afile = $qfile;
+ $afile =~ s/\.cql$/.xcql/;
+ print " query $_ - $query ";
+ $ntests++;
+ my $correct = read_file("$norman < $afile |");
+ my $tested = read_file("$compiler < $qfile | $norman |");
+ if (!$tested) {
+ print "\n *** test compiler exited non-zero\n";
+ } elsif ($tested eq $correct) {
+ print "OK\n";
+ $ncorrect++;
+ } else {
+ print "\n *** XCQL output differs from $afile\n";
+ print "=== tested ===\n$tested";
+ print "=== end ===\n";
+ }
+ }
+}
+
+print sprintf("%d of %d passed: %d%%\n",
+ $ncorrect, $ntests, (100 * $ncorrect) / $ntests);
+
+sub read_file {
+ my($name) = @_;
+
+ $name = "<$name" if $name !~ /\|$/;
+ my $fh = new IO::File("$name")
+ or die "can't read '$name': $!";
+ my $contents = join('', <$fh>);
+ $fh->close();
+ return $contents;
+}
--- /dev/null
+name
+*.cql
--- /dev/null
+<searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>cat</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>cat</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>comp.os.linux</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>xml:element</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term><xml:element></term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>=</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>prox/distance<3/unit=word</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>cat</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>dog</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>all</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>prox</term>
+</searchClause>
--- /dev/null
+name
+*.cql
--- /dev/null
+<searchClause>
+ <index>title</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>fish</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>title</index>
+ <relation>
+ <value>exact</value>
+ </relation>
+ <term>fish</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>title</index>
+ <relation>
+ <value>any</value>
+ </relation>
+ <term>fish</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>title</index>
+ <relation>
+ <value>all</value>
+ </relation>
+ <term>fish</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>title</index>
+ <relation>
+ <value>></value>
+ </relation>
+ <term>9</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>title</index>
+ <relation>
+ <value>>=</value>
+ </relation>
+ <term>23</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>dc.title</index>
+ <relation>
+ <value>any</value>
+ </relation>
+ <term>fish chips</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>dc.title</index>
+ <relation>
+ <value>any</value>
+ <modifiers>
+ <modifier>
+ <type>stem</type>
+ </modifier>
+ </modifiers>
+ </relation>
+ <term>fish</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>dc.fish</index>
+ <relation>
+ <value>all</value>
+ <modifiers>
+ <modifier>
+ <type>stem</type>
+ </modifier>
+ <modifier>
+ <type>fuzzy</type>
+ </modifier>
+ </modifiers>
+ </relation>
+ <term>fish chips</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>title</index>
+ <relation>
+ <value>any</value>
+ </relation>
+ <term>frog</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>dc.title</index>
+ <relation>
+ <value>any</value>
+ <modifiers>
+ <modifier>
+ <type>stem</type>
+ </modifier>
+ </modifiers>
+ </relation>
+ <term>frog pond</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>dc.title</index>
+ <relation>
+ <value>any</value>
+ </relation>
+ <term>fish frog chicken</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>dc.title</index>
+ <relation>
+ <value>=</value>
+ <modifiers>
+ <modifier>
+ <type>rel.algorithm</type>
+ <comparison>=</comparison>
+ <value>CORI</value>
+ </modifier>
+ </modifiers>
+ </relation>
+ <term>squid</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>author</index>
+ <relation>
+ <value>any</value>
+ <modifiers>
+ <modifier>
+ <type>f.foo</type>
+ </modifier>
+ <modifier>
+ <type>b.bar</type>
+ <comparison>></comparison>
+ <value>1</value>
+ </modifier>
+ </modifiers>
+ </relation>
+ <term>sanderson taylor</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>numberOfLegs</index>
+ <relation>
+ <value><=</value>
+ </relation>
+ <term>4</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>numberOfLegs</index>
+ <relation>
+ <value><></value>
+ </relation>
+ <term>4</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>title</index>
+ <relation>
+ <value>==</value>
+ </relation>
+ <term>jaws</term>
+</searchClause>
--- /dev/null
+name
+*.cql
--- /dev/null
+<triple>
+ <boolean>
+ <value>or</value>
+ </boolean>
+ <leftOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>cat</term>
+ </searchClause>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>dog</term>
+ </searchClause>
+ </rightOperand>
+</triple>
--- /dev/null
+<triple>
+ <boolean>
+ <value>and</value>
+ </boolean>
+ <leftOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>cat</term>
+ </searchClause>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>fish</term>
+ </searchClause>
+ </rightOperand>
+</triple>
--- /dev/null
+<triple>
+ <boolean>
+ <value>not</value>
+ </boolean>
+ <leftOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>cat</term>
+ </searchClause>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>frog</term>
+ </searchClause>
+ </rightOperand>
+</triple>
--- /dev/null
+<triple>
+ <boolean>
+ <value>not</value>
+ </boolean>
+ <leftOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>cat</term>
+ </searchClause>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>frog</term>
+ </searchClause>
+ </rightOperand>
+</triple>
--- /dev/null
+<triple>
+ <boolean>
+ <value>not</value>
+ </boolean>
+ <leftOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>cat</term>
+ </searchClause>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>fish food</term>
+ </searchClause>
+ </rightOperand>
+</triple>
--- /dev/null
+<triple>
+ <boolean>
+ <value>and</value>
+ </boolean>
+ <leftOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>xml</term>
+ </searchClause>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>prox///</term>
+ </searchClause>
+ </rightOperand>
+</triple>
--- /dev/null
+<triple>
+ <boolean>
+ <value>and</value>
+ </boolean>
+ <leftOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>fred</term>
+ </searchClause>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>any</term>
+ </searchClause>
+ </rightOperand>
+</triple>
--- /dev/null
+<triple>
+ <boolean>
+ <value>or</value>
+ </boolean>
+ <leftOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>fred</term>
+ </searchClause>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>all</term>
+ </searchClause>
+ </rightOperand>
+</triple>
--- /dev/null
+<triple>
+ <boolean>
+ <value>not</value>
+ </boolean>
+ <leftOperand>
+ <triple>
+ <boolean>
+ <value>and</value>
+ </boolean>
+ <leftOperand>
+ <triple>
+ <boolean>
+ <value>or</value>
+ </boolean>
+ <leftOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>a</term>
+ </searchClause>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>b</term>
+ </searchClause>
+ </rightOperand>
+ </triple>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>c</term>
+ </searchClause>
+ </rightOperand>
+ </triple>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>d</term>
+ </searchClause>
+ </rightOperand>
+</triple>
--- /dev/null
+name
+*.cql
--- /dev/null
+<triple>
+ <boolean>
+ <value>and</value>
+ </boolean>
+ <leftOperand>
+ <searchClause>
+ <index>bath.author</index>
+ <relation>
+ <value>any</value>
+ </relation>
+ <term>fish</term>
+ </searchClause>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>dc.title</index>
+ <relation>
+ <value>all</value>
+ </relation>
+ <term>cat dog</term>
+ </searchClause>
+ </rightOperand>
+</triple>
--- /dev/null
+<triple>
+ <boolean>
+ <value>or</value>
+ </boolean>
+ <leftOperand>
+ <searchClause>
+ <index>title</index>
+ <relation>
+ <value>any</value>
+ <modifiers>
+ <modifier>
+ <type>stem</type>
+ </modifier>
+ </modifiers>
+ </relation>
+ <term>fish dog</term>
+ </searchClause>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>and</term>
+ </searchClause>
+ </rightOperand>
+</triple>
--- /dev/null
+name
+*.cql
--- /dev/null
+<triple>
+ <boolean>
+ <value>prox</value>
+ </boolean>
+ <leftOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>cat</term>
+ </searchClause>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>hat</term>
+ </searchClause>
+ </rightOperand>
+</triple>
--- /dev/null
+<triple>
+ <boolean>
+ <value>prox</value>
+ <modifiers>
+ <modifier>
+ <type>distance</type>
+ <comparison>=</comparison>
+ <value>3</value>
+ </modifier>
+ <modifier>
+ <type>unit</type>
+ <comparison>=</comparison>
+ <value>word</value>
+ </modifier>
+ <modifier>
+ <type>ordered</type>
+ </modifier>
+ </modifiers>
+ </boolean>
+ <leftOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>cat</term>
+ </searchClause>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>hat</term>
+ </searchClause>
+ </rightOperand>
+</triple>
--- /dev/null
+<triple>
+ <boolean>
+ <value>prox</value>
+ <modifiers>
+ <modifier>
+ <type>distance</type>
+ <comparison><</comparison>
+ <value>3</value>
+ </modifier>
+ </modifiers>
+ </boolean>
+ <leftOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>cat</term>
+ </searchClause>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>hat</term>
+ </searchClause>
+ </rightOperand>
+</triple>
--- /dev/null
+<triple>
+ <boolean>
+ <value>prox</value>
+ <modifiers>
+ <modifier>
+ <type>unit</type>
+ <comparison>=</comparison>
+ <value>sentence</value>
+ </modifier>
+ </modifiers>
+ </boolean>
+ <leftOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>fish food</term>
+ </searchClause>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>and</term>
+ </searchClause>
+ </rightOperand>
+</triple>
--- /dev/null
+<triple>
+ <boolean>
+ <value>prox</value>
+ <modifiers>
+ <modifier>
+ <type>distance</type>
+ <comparison><=</comparison>
+ <value>5</value>
+ </modifier>
+ </modifiers>
+ </boolean>
+ <leftOperand>
+ <searchClause>
+ <index>title</index>
+ <relation>
+ <value>all</value>
+ </relation>
+ <term>chips frog</term>
+ </searchClause>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>exact</term>
+ </searchClause>
+ </rightOperand>
+</triple>
--- /dev/null
+<triple>
+ <boolean>
+ <value>prox</value>
+ <modifiers>
+ <modifier>
+ <type>distance</type>
+ <comparison>></comparison>
+ <value>5</value>
+ </modifier>
+ <modifier>
+ <type>unit</type>
+ <comparison>=</comparison>
+ <value>element</value>
+ </modifier>
+ </modifiers>
+ </boolean>
+ <leftOperand>
+ <searchClause>
+ <index>dc.author</index>
+ <relation>
+ <value>==</value>
+ </relation>
+ <term>jones</term>
+ </searchClause>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>title</index>
+ <relation>
+ <value>>=</value>
+ </relation>
+ <term>smith</term>
+ </searchClause>
+ </rightOperand>
+</triple>
--- /dev/null
+<triple>
+ <boolean>
+ <value>prox</value>
+ </boolean>
+ <leftOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>cat</term>
+ </searchClause>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>hat</term>
+ </searchClause>
+ </rightOperand>
+</triple>
--- /dev/null
+<triple>
+ <boolean>
+ <value>and</value>
+ <modifiers>
+ <modifier>
+ <type>rel.sumofscores</type>
+ </modifier>
+ </modifiers>
+ </boolean>
+ <leftOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>a</term>
+ </searchClause>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>b</term>
+ </searchClause>
+ </rightOperand>
+</triple>
--- /dev/null
+<triple>
+ <boolean>
+ <value>and</value>
+ <modifiers>
+ <modifier>
+ <type>rel.algorithm</type>
+ <comparison>=</comparison>
+ <value>CORI</value>
+ </modifier>
+ </modifiers>
+ </boolean>
+ <leftOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>a</term>
+ </searchClause>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>b</term>
+ </searchClause>
+ </rightOperand>
+</triple>
--- /dev/null
+name
+*.cql
--- /dev/null
+<searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>cat^</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>cat</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>^cat says "fish"</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>cat*fish</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>cat?dog</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>^cat*fishdog"horse?</term>
+</searchClause>
--- /dev/null
+name
+*.cql
--- /dev/null
+<triple>
+ <boolean>
+ <value>and</value>
+ </boolean>
+ <leftOperand>
+ <triple>
+ <boolean>
+ <value>or</value>
+ </boolean>
+ <leftOperand>
+ <triple>
+ <boolean>
+ <value>or</value>
+ </boolean>
+ <leftOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>cat</term>
+ </searchClause>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>dog</term>
+ </searchClause>
+ </rightOperand>
+ </triple>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>horse</term>
+ </searchClause>
+ </rightOperand>
+ </triple>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>frog</term>
+ </searchClause>
+ </rightOperand>
+</triple>
--- /dev/null
+<triple>
+ <boolean>
+ <value>or</value>
+ </boolean>
+ <leftOperand>
+ <triple>
+ <boolean>
+ <value>and</value>
+ </boolean>
+ <leftOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>cat</term>
+ </searchClause>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>dog</term>
+ </searchClause>
+ </rightOperand>
+ </triple>
+ </leftOperand>
+ <rightOperand>
+ <triple>
+ <boolean>
+ <value>and</value>
+ </boolean>
+ <leftOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>horse</term>
+ </searchClause>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>frog</term>
+ </searchClause>
+ </rightOperand>
+ </triple>
+ </rightOperand>
+</triple>
--- /dev/null
+<triple>
+ <boolean>
+ <value>and</value>
+ </boolean>
+ <leftOperand>
+ <triple>
+ <boolean>
+ <value>and</value>
+ </boolean>
+ <leftOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>cat</term>
+ </searchClause>
+ </leftOperand>
+ <rightOperand>
+ <triple>
+ <boolean>
+ <value>or</value>
+ </boolean>
+ <leftOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>horse</term>
+ </searchClause>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>frog</term>
+ </searchClause>
+ </rightOperand>
+ </triple>
+ </rightOperand>
+ </triple>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>chips</term>
+ </searchClause>
+ </rightOperand>
+</triple>
--- /dev/null
+name
+*.cql
--- /dev/null
+<searchClause>
+ <prefixes>
+ <prefix>
+ <name>foo</name>
+ <identifier>http://www.loc.gov/zing/cql/dc-indexes/</identifier>
+ </prefix>
+ </prefixes>
+ <index>dc.title</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>fish</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <prefixes>
+ <prefix>
+ <identifier>http://www.loc.gov/zing/cql/dc-indexes/</identifier>
+ </prefix>
+ </prefixes>
+ <index>title</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>fish</term>
+</searchClause>
--- /dev/null
+<triple>
+ <prefixes>
+ <prefix>
+ <name>foo</name>
+ <identifier>http://www.loc.gov/zing/cql/dc-indexes</identifier>
+ </prefix>
+ <prefix>
+ <name>ccg</name>
+ <identifier>http://srw.o-r-g.org/cql/indexSets/ccg/</identifier>
+ </prefix>
+ </prefixes>
+ <boolean>
+ <value>and</value>
+ </boolean>
+ <leftOperand>
+ <searchClause>
+ <index>foo.title</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>fish</term>
+ </searchClause>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>ccg.force</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>3</term>
+ </searchClause>
+ </rightOperand>
+</triple>
--- /dev/null
+name
+*.cql
--- /dev/null
+<triple>
+ <boolean>
+ <value>and</value>
+ </boolean>
+ <leftOperand>
+ <triple>
+ <boolean>
+ <value>or</value>
+ </boolean>
+ <leftOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>any</term>
+ </searchClause>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>all:stem</term>
+ </searchClause>
+ </rightOperand>
+ </triple>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>all contains</index>
+ <relation>
+ <value>any</value>
+ </relation>
+ <term>prox proxfuzzy</term>
+ </searchClause>
+ </rightOperand>
+</triple>
--- /dev/null
+<searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>any</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term></term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <prefixes>
+ <prefix>
+ <identifier>any</identifier>
+ </prefix>
+ <prefix>
+ <name>any</name>
+ <identifier>exact</identifier>
+ </prefix>
+ </prefixes>
+ <index>any</index>
+ <relation>
+ <value>></value>
+ </relation>
+ <term>any</term>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>sortby</term>
+ <sortKeys>
+ <key>
+ <index>sortby</index>
+ </key>
+ </sortKeys>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>sortby</term>
+ <sortKeys>
+ <key>
+ <index>sortby</index>
+ </key>
+ <key>
+ <index>sortby</index>
+ </key>
+ <key>
+ <index>sortby</index>
+ </key>
+ </sortKeys>
+</searchClause>
--- /dev/null
+name
+*.cql
--- /dev/null
+<searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>kernighan</term>
+ <sortKeys>
+ <key>
+ <index>title</index>
+ </key>
+ </sortKeys>
+</searchClause>
--- /dev/null
+<triple>
+ <boolean>
+ <value>and</value>
+ </boolean>
+ <leftOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>kernighan</term>
+ </searchClause>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>ritchie</term>
+ </searchClause>
+ </rightOperand>
+ <sortKeys>
+ <key>
+ <index>title</index>
+ </key>
+ </sortKeys>
+</triple>
--- /dev/null
+<searchClause>
+ <index>dc.creator</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>kernighan</term>
+ <sortKeys>
+ <key>
+ <index>dc.title</index>
+ </key>
+ </sortKeys>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>dc.creator</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>kernighan</term>
+ <sortKeys>
+ <key>
+ <index>numberOfLegs</index>
+ <modifiers>
+ <modifier>
+ <type>cql.number</type>
+ </modifier>
+ </modifiers>
+ </key>
+ </sortKeys>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>dc.creator</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>kernighan</term>
+ <sortKeys>
+ <key>
+ <index>dc.title</index>
+ <modifiers>
+ <modifier>
+ <type>sort.respectcase</type>
+ </modifier>
+ </modifiers>
+ </key>
+ </sortKeys>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>dc.creator</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>kernighan</term>
+ <sortKeys>
+ <key>
+ <index>dc.title</index>
+ <modifiers>
+ <modifier>
+ <type>sort.respectcase</type>
+ </modifier>
+ <modifier>
+ <type>sort.descending</type>
+ </modifier>
+ </modifiers>
+ </key>
+ </sortKeys>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>dc.creator</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>kernighan</term>
+ <sortKeys>
+ <key>
+ <index>dc.date</index>
+ </key>
+ <key>
+ <index>dc.title</index>
+ </key>
+ </sortKeys>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>dc.creator</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>kernighan</term>
+ <sortKeys>
+ <key>
+ <index>dc.date</index>
+ <modifiers>
+ <modifier>
+ <type>sort.missingomit</type>
+ </modifier>
+ </modifiers>
+ </key>
+ </sortKeys>
+</searchClause>
--- /dev/null
+<searchClause>
+ <index>dc.creator</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>kernighan</term>
+ <sortKeys>
+ <key>
+ <index>dc.date</index>
+ <modifiers>
+ <modifier>
+ <type>sort.missingvalue</type>
+ <comparison>=</comparison>
+ <value>1970</value>
+ </modifier>
+ </modifiers>
+ </key>
+ </sortKeys>
+</searchClause>
--- /dev/null
+<searchClause>
+ <prefixes>
+ <prefix>
+ <name>dc</name>
+ <identifier>http://deepcustard.org/1.0</identifier>
+ </prefix>
+ </prefixes>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>blah</term>
+ <sortKeys>
+ <key>
+ <index>dc.custardDepth</index>
+ </key>
+ </sortKeys>
+</searchClause>
--- /dev/null
+<searchClause>
+ <prefixes>
+ <prefix>
+ <name>ns1</name>
+ <identifier>http://uri1</identifier>
+ </prefix>
+ <prefix>
+ <name>ns2</name>
+ <identifier>http://uri2</identifier>
+ </prefix>
+ </prefixes>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>whatever</term>
+ <sortKeys>
+ <key>
+ <index>ns1.key</index>
+ <modifiers>
+ <modifier>
+ <type>a</type>
+ </modifier>
+ <modifier>
+ <type>b</type>
+ </modifier>
+ <modifier>
+ <type>c</type>
+ <comparison>=</comparison>
+ <value>1</value>
+ </modifier>
+ </modifiers>
+ </key>
+ <key>
+ <index>ns2.key2</index>
+ </key>
+ </sortKeys>
+</searchClause>
--- /dev/null
+<searchClause>
+ <prefixes>
+ <prefix>
+ <name>dc</name>
+ <identifier>x</identifier>
+ </prefix>
+ </prefixes>
+ <index>b</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>c</term>
+ <sortKeys>
+ <key>
+ <index>d</index>
+ </key>
+ </sortKeys>
+</searchClause>
--- /dev/null
+<searchClause>
+ <prefixes>
+ <prefix>
+ <name>dc</name>
+ <identifier>x</identifier>
+ </prefix>
+ </prefixes>
+ <index>b</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>c</term>
+ <sortKeys>
+ <key>
+ <index>d</index>
+ </key>
+ </sortKeys>
+</searchClause>
--- /dev/null
+<triple>
+ <prefixes>
+ <prefix>
+ <name>dc</name>
+ <identifier>x</identifier>
+ </prefix>
+ </prefixes>
+ <boolean>
+ <value>and</value>
+ </boolean>
+ <leftOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>c1</term>
+ </searchClause>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>c2</term>
+ </searchClause>
+ </rightOperand>
+ <sortKeys>
+ <key>
+ <index>d</index>
+ </key>
+ </sortKeys>
+</triple>
--- /dev/null
+<searchClause>
+ <prefixes>
+ <prefix>
+ <name>dc</name>
+ <identifier>http://deepcustard.org</identifier>
+ </prefix>
+ <prefix>
+ <name>dc</name>
+ <identifier>http://dublincore.org</identifier>
+ </prefix>
+ </prefixes>
+ <index>dc.title</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>jaws</term>
+ <sortKeys>
+ <key>
+ <index>dc.custardDepth</index>
+ </key>
+ </sortKeys>
+</searchClause>
--- /dev/null
+<triple>
+ <prefixes>
+ <prefix>
+ <name>dc</name>
+ <identifier>http://deepcustard.org</identifier>
+ </prefix>
+ </prefixes>
+ <boolean>
+ <value>or</value>
+ </boolean>
+ <leftOperand>
+ <searchClause>
+ <index>cql.serverChoice</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>fish</term>
+ </searchClause>
+ </leftOperand>
+ <rightOperand>
+ <searchClause>
+ <prefixes>
+ <prefix>
+ <name>dc</name>
+ <identifier>http://dublincore.org</identifier>
+ </prefix>
+ </prefixes>
+ <index>dc.title</index>
+ <relation>
+ <value>=</value>
+ </relation>
+ <term>jaws</term>
+ </searchClause>
+ </rightOperand>
+ <sortKeys>
+ <key>
+ <index>dc.custardDepth</index>
+ </key>
+ </sortKeys>
+</triple>
--- /dev/null
+#!/bin/sh
+
+
+if [ $# != 1 ]; then
+ echo "Usage: $0 <test-name>" >&2
+ echo " e.g. $0 01/02" >&2
+ exit 1
+fi
+
+### Warning: nasty hard-coded choices
+( echo "=== Adam ==="
+ ../../../srw/cql/cql2xcql < sections/$1.cql ) > /tmp/adam
+( echo "=== Mike ==="
+ ../../bin/CQLParser < sections/$1.cql ) > /tmp/mike
+sdiff -w 80 /tmp/adam /tmp/mike
--- /dev/null
+#!/usr/bin/perl -w
+
+#
+# Copyright (c) 2002, DecisionSoft Limited All rights reserved.
+# Please see:
+# http://software.decisionsoft.com/license.html
+# for more information.
+#
+
+# $Revision: 1.2 $
+#
+# xmlpp: XML pretty printing
+#
+
+# For custom attribute sorting create an attributeOrdering.txt file that
+# lists each attributes separated by a newline in the order you would like
+# them to be sorted separated by a newline. Then use the -s option.
+
+use FileHandle;
+use Fcntl;
+use Getopt::Std;
+
+use vars qw($opt_h $opt_H $opt_s $opt_z $opt_t $opt_e $opt_S $opt_c $opt_n $opt_l);
+
+my $indent=0;
+my $textContent='';
+my $lastTag=undef;
+my $output;
+my $inAnnotation = 0;
+
+
+if (!getopts('nzhHsteScl:') or $opt_h) {
+ usage();
+}
+
+my $indentSize = $opt_l || 2;
+
+if ($opt_s){
+
+# expect to find attributeOrdering.txt file in same directory
+# as xmlpp is being run from
+
+ my $scriptDir = $0;
+ if ($scriptDir =~ m#/#){
+ $scriptDir =~ s#/[^/]+$##;
+ }
+ else{
+ $scriptDir =".";
+ }
+
+ # get attribute ordering from external file
+ if (open(SORTLIST, "<$scriptDir/attributeOrdering.txt")) {
+ @sortlist = <SORTLIST>;
+ chomp @sortlist;
+ close (SORTLIST);
+ @specialSort = grep(/^\w+/, @sortlist);
+ }
+ else {
+ print STDERR "Could not open $scriptDir/attributeOrdering.txt: $!\nWARNING attribute sorting will only be alphabetic\n\n";
+ }
+}
+
+
+# set line separator to ">" speeding up parsing of XML files
+# with no line breaks
+
+$/ = ">";
+
+
+my $sortAttributes = $opt_s;
+my $newLineComments = $opt_c;
+my $splitAttributes = $opt_t;
+my $schemaHackMode = $opt_S;
+my $normaliseWhiteSpace = $opt_n;
+
+my $filename = $ARGV[0];
+if ($opt_z && (!$filename or $filename eq '-')) {
+ print STDERR "Error: I can't edit STDIN in place.\n";
+ usage();
+}
+
+if (!$opt_z && scalar(@ARGV) > 1) {
+ print STDERR "Warning: Multiple files specified without -z option\n";
+}
+
+my $fh;
+
+my $stdin;
+
+if (!$filename or $filename eq '-') {
+ $fh=*STDIN;
+ $stdin=1;
+} else {
+ $fh = open_next_file() or exit(1);
+ $stdin=0;
+}
+
+do {
+ $indent=0;
+ $textContent='';
+ $lastTag=undef;
+ $output = '';
+ my $re_name = "(?:[A-Za-z0-9_:][A-Za-z0-9_:.-]*)";
+ my $re_attr = "(?:'[^']*'|\"[^\"]*\")";
+ my $input;
+
+ while ($input .= <$fh>) {
+ while ($input) {
+ if ($input =~ s/^<($re_name)((?:\s+$re_name\s*=\s*$re_attr)*\s*)(\/?)>(.*)$/$4/s ) {
+ my %attr;
+ my ($name,$attr,$selfclose) = ($1,$2,$3);
+ while ($attr =~ m/($re_name)\s*=\s*($re_attr)/gs) {
+ my ($name,$value) = ($1,$2);
+ $value =~ s/^["'](.*)["']$/$1/s;
+ $attr{$name} = $value;
+ }
+ if ($opt_e) {
+ parseStart($name, 0, %attr);
+ if ($selfclose) { parseEnd($name) }
+ } else {
+ parseStart($name, $selfclose, %attr);
+ }
+ } elsif ($input =~ s/^<\/($re_name)\s*>(.*)$/$2/s) {
+ parseEnd($1);
+ } elsif ($input =~ s/^<!--(.*?)-->(.*)$/$2/s) {
+ parseComment($1);
+ } elsif ($input =~ s/^([^<]+)(.*)$/$2/s) {
+ parseDefault($1);
+ } elsif ($input =~ s/^(<\?[^>]*\?>)(.*)$/$2/s) {
+ parsePI("$1\n");
+ } elsif ($input =~ s/^(<\!DOCTYPE[^\[>]*(\[[^\]]*\])?[^>]*>)(.*)$/$3/s) {
+ parseDoctype("$1");
+ } else {
+ last;
+ }
+ }
+ if (eof($fh)) {
+ last;
+ }
+ }
+
+
+ if ($input) {
+ $input =~ m/([^\n]+)/gs;
+ print STDERR "WARNING: junk remaining on input: $1\n";
+ }
+ $fh->close();
+
+ if (!$opt_z) {
+ if(!$opt_H){
+ print "$output\n"
+ } else {
+ print html_escape($output)."\n"
+ }
+ } else {
+ if ($input) {
+ print STDERR "Not overwriting file\n";
+ } else {
+ open FOUT,"> $filename" or die "Cannot overwrite file: $!";
+ if(!$opt_H){
+ print FOUT "$output\n"
+ } else {
+ print FOUT html_escape($output)."\n"
+ }
+ close FOUT
+ }
+ }
+} while (
+ !$stdin && $opt_z && ($fh = open_next_file(\$filename))
+ );
+
+
+
+sub parseStart {
+ my $s = shift;
+ my $selfclose = shift;
+ my %attr = @_;
+
+ $textContent =~ s/\s+$//;
+ printContent($textContent);
+
+ if($inAnnotation) {
+ return;
+ }
+
+ if($schemaHackMode and $s =~ m/(^|:)annotation$/) {
+ $inAnnotation = 1;
+ $textContent = '';
+ $lastTag = 1;
+ return;
+ }
+ if (length($output)) {
+ $output .= "\n";
+ }
+
+ $output .= " " x ($indent * $indentSize);
+ $output .= "<$s";
+ my @k = keys %attr;
+
+ if ($sortAttributes && (scalar(@k) > 1) ){
+
+ my @alphaSorted;
+ my @needSpecialSort;
+ my @final;
+ my $isSpecial;
+
+ # sort attributes alphabetically (default ordering)
+ @alphaSorted = sort @k;
+
+ # read through sorted list, if attribute doesn't have specified
+ # sort order, push it onto the end of the final array (this maintains
+ # alphabetic order). Else create a list that has attributes needing
+ # special ordering.
+ foreach $attribute (@alphaSorted){
+ $isSpecial = 0;
+ foreach $sortAttrib (@specialSort){
+ if ($attribute eq $sortAttrib){
+ push @needSpecialSort, $attribute;
+ $isSpecial = 1;
+ }
+ }
+ if (!$isSpecial){
+ push @final, $attribute;
+ }
+ }
+
+ # now read through the specialSort list backwards looking for
+ # any match in the needSpecialSort list. Unshift this onto the
+ # front of the final array to maintain proper order.
+ foreach my $attribute (reverse @specialSort){
+ foreach (@needSpecialSort){
+ if ($attribute eq $_){
+ unshift @final, $attribute;
+ }
+ }
+ }
+
+ @k = @final;
+ }
+
+ foreach my $attr (@k) {
+ #
+ # Remove (min|max)Occurs = 1 if schemaHackMode
+ #
+ if ($schemaHackMode and $attr =~ m/^(minOccurs|maxOccurs)$/ and $attr{$attr} eq "1") {
+ next;
+ }
+
+ if ($splitAttributes) {
+ $output .= "\n"." " x ($indent * $indentSize) ." ";
+ }
+ if ($attr{$attr} =~ /'/) {
+ $output .= " $attr=\"$attr{$attr}\"";
+ } else {
+ $output .= " $attr='$attr{$attr}'";
+ }
+ }
+ if ($splitAttributes and @k) {
+ $output .= "\n"." " x ($indent * $indentSize);
+ }
+ if ($selfclose) {
+ $output .= " />";
+ $lastTag = 0;
+ } else {
+ $output .= ">";
+ $indent++;
+ $lastTag = 1;
+ }
+ $textContent = '';
+}
+
+sub parseEnd {
+ my $s = shift;
+
+ if($inAnnotation) {
+ if($s =~ m/(^|:)annotation$/) {
+ $inAnnotation = 0;
+ }
+ return;
+ }
+
+ if($normaliseWhiteSpace) {
+ $textContent =~ s/^\s*(.*?)\s*$/$1/;
+ }
+ $indent--;
+ printContent($textContent);
+ if ($lastTag == 0) {
+ $output .= "\n";
+ $output .= " " x ($indent * $indentSize);
+ }
+ $output .= "</$s>";
+ $textContent = '';
+ $lastTag = 0;
+}
+
+sub parseDefault {
+ my $s = shift;
+ if($inAnnotation) { return }
+ $textContent .= "$s";
+}
+
+sub parsePI {
+ my $s = shift;
+ $output .= "$s";
+}
+
+sub parseDoctype {
+ my $s = shift;
+ if ($s =~ /^([^\[]*\[)([^\]]*)(\].*)$/ms) {
+ $start = $1;
+ $DTD = $2;
+ $finish = $3;
+ $DTD =~ s/\</\n \</msg;
+ $output .= "$start$DTD\n$finish\n";
+ } else {
+ $output .= "$s";
+ }
+}
+
+sub parseComment {
+ my $s = shift;
+ if($inAnnotation) { return }
+ printContent($textContent,1);
+ if ($s =~ /([^\<]*)(<.*>)(.*)/ms) {
+ $start = $1;
+ $xml = $2;
+ $finish = $3;
+ $xml =~ s/\</\n\</msg;
+ $xml =~ s/(\n\s*\n?)+/\n/msg;
+ $xml =~ s/^\s*//msg;
+ $xml =~ s/\s*$//msg;
+ $s = "$start\n$xml\n$finish";
+ }
+ $s =~ s/\n\s*$/\n /msg;
+ if ($newLineComments) {
+ $output .= "\n<!--$s-->\n";
+ } else {
+ $output .= "<!--$s-->";
+ }
+ $textContent='';
+}
+
+sub printContent {
+ my $s = shift;
+ my $printLF = shift;
+ my ($LF,$ret) = ("","");
+
+ if ($s =~ m/\n\s*$/) {
+ $LF = "\n";
+ }
+ if ($s =~ m/^[\s\n]*$/) {
+ $ret = undef;
+ } else {
+ $output .= "$s";
+ $ret = 1;
+ }
+ if ($printLF) {
+ $output .= $LF;
+ }
+}
+
+
+sub html_escape {
+ my $s = shift;
+ $s =~ s/&/&/gsm;
+ $s =~ s/</</gsm;
+ $s =~ s/>/>/gsm;
+ return $s;
+}
+
+sub open_next_file {
+ my $filename = shift;
+ $$filename = shift @ARGV;
+ while ($$filename and ! -f $$filename) {
+ print STDERR "WARNING: Could not find file: $$filename\n";
+ $$filename = shift @ARGV;
+ }
+ if(!$$filename) {
+ return undef;
+ }
+ my $fh = new FileHandle;
+ $fh->open("< $$filename") or die "Can't open $$filename: $!";
+ return $fh;
+}
+
+sub usage {
+ print STDERR <<EOF;
+usage: $0 [ options ] [ file.xml ... ]
+
+options:
+ -h display this help message
+ -H escape characters (useful for further processing)
+ -t split attributes, one per line (useful for diff)
+ -s sort attributes (useful for diff)
+ -z in place edit (zap)
+ -e expand self closing tags (useful for diff)
+ -S schema hack mode (used by xmldiff)
+ -c place comments on new line.
+ -n normalise whitespace (remove leading and trailing whitespace from nodes
+ with text content.
+ -l <num> Indent each level by <num> spaces [default: 2]
+EOF
+ exit 1;
+}
+