deprecated/buildtools/buildsystemtools/lib/XML/XQL.pm
author lorewang
Wed, 17 Nov 2010 11:24:29 +0800
changeset 685 39f7ecf8fbc7
parent 655 3f65fd25dfd4
permissions -rw-r--r--
pull from trunk
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
655
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     1
############################################################################
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     2
# Copyright (c) 1998,1999 Enno Derksen
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     3
# All rights reserved.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     4
# This program is free software; you can redistribute it and/or modify it
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     5
# under the same terms as Perl itself. 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     6
############################################################################
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     7
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     8
# To do (in no particular order):
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
     9
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    10
# - Element tag names that are the same as a XQL keyword (e.g. "or", "not", ..)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    11
#   are currently not supported. The parser and lexer needs to be smarter and
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    12
#   know what context they are in.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    13
# - output using xql:result etc.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    14
# - xml:space=preserve still needs to be adhered to in text() etc.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    15
#   - I already added xql_preserveSpace. Still need to use it in (raw)text() etc.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    16
# - XQL functions (like value()) should probably work on input lists > 1 node
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    17
#   (The code was changed, but it needs to be tested. ancestor() wasn't fixed)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    18
# - verify implementation of xql_namespace
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    19
# - verify implementation of end, index
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    20
# - check passing of context to the solve() methods
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    21
# - functions/methods may be wrong. They receive the entire LHS set,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    22
#   so count() is right, but the rest may be wrong!
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    23
# - may need to use different comment delimiters, '#' may be used in future XQL
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    24
#   definition (according to Joe Lapp, one of the XQL spec authors)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    25
# - caching of Node xql_values (?)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    26
# - finish the Date class
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    27
#   - discuss which classes: Date, Time, and/or DateTime ?
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    28
# - conversion of Query result to Perl primitives, i.e. how do we return the
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    29
#   result of a query.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    30
# - add support for ordering/formatting the query results, see XML-QL
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    31
# - discuss typecasting mechanism
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    32
# - error reporting mechanism
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    33
#   - yyerror handler doesn't seem to work
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    34
#   - passing intermediate exceptions ($@) to the user
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    35
#   - more debugging support
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    36
# - subst, map etc. 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    37
#   - use rawText for Nodes?
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    38
#     - recurse or not?
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    39
# - text/rawText default - recurse or not? 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    40
#   - what should default value() implementation use?
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    41
# - check if all Syntactic Constraints in XQL spec are implemented
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    42
# - support all node types, i.e. Notation, Attlist etc.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    43
#   - sorting in 'document order' doesn't work yet for 'other' DOM nodes
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    44
# - generateFunction - support functions that return lists?
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    45
# - match() function - what should it return?
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    46
# - keeping track of reference nodes not always done right
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    47
#   - also think about Perl builtin functions
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    48
# - conversion to Perl number throws warnings with -w (in comparisons etc.)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    49
# - sorting
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    50
#   - add sorting by attribute name (within same element)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    51
#     (or other criteria)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    52
#   - optional sorting in $union$ ?
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    53
#     - could add a flag that says "don't worry about document order for $union$"
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    54
#   - user defined sort?
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    55
# - OPTIMIZE!
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    56
#   - Subscript operator
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    57
#   - Filter operator
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    58
#   - etc.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    59
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    60
package XML::XQL;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    61
use strict;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    62
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    63
use Carp;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    64
use XML::RegExp;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    65
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    66
use vars qw( @EXPORT $VERSION 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    67
	     $ContextStart $ContextEnd $BoldOn $BoldOff 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    68
	     %Func %Method %FuncArgCount
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    69
	     %AllowedOutsideSubquery %ConstFunc %ExpandedType
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    70
	     $Restricted $Included $ReXQLName
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    71
	     %CompareOper $Token_q $Token_qq $LAST_SORT_KEY
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    72
	   );
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    73
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    74
@EXPORT = qw( $VERSION $Restricted $Included );
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    75
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    76
BEGIN
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    77
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    78
    $VERSION = '0.63';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    79
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    80
    die "XML::XQL is already used/required" if defined $Included;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    81
    $Included = 1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    82
    
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    83
    # From XQL spec (The '-' was added to allow XPath style function names.)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    84
    $ReXQLName =	  "(?:[-a-zA-Z_]+\\w*)";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    85
    
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    86
    $Token_q = undef;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    87
    $Token_qq = undef;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    88
    
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    89
    $Restricted = 0 unless defined $Restricted;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    90
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    91
    if (not $Restricted)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    92
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    93
	# Allow names with Perl package prefixes
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    94
	$ReXQLName = "(?:$ReXQLName(?:::$ReXQLName)*)";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    95
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    96
	# Support q// and qq// strings
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    97
	$Token_q = "q";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    98
	$Token_qq = "qq";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
    99
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   100
};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   101
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   102
# To save the user some typing for the simplest cases
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   103
sub solve
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   104
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   105
    my ($expr, @args) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   106
    my $query = new XML::XQL::Query (Expr => $expr);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   107
    my @result = $query->solve (@args);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   108
    $query->dispose;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   109
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   110
    @result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   111
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   112
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   113
#---------- Parser related stuff ----------------------------------------------
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   114
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   115
# Find (nested) closing delimiter in q{} or qq{} strings
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   116
sub parse_q
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   117
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   118
    my ($qname, $q, $str, $d1, $d2) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   119
    my ($match) = "";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   120
    my ($found);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   121
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   122
    while ($str =~ /^([^$d1$d2]*)($d1|($d2))(.*)/s)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   123
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   124
	defined ($3) and return ($4, $match . $1);		# $d2 found
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   125
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   126
	# match delimiters recursively
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   127
	$match .= $1 . $2;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   128
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   129
	($str, $found) = parse_q ($qname, $q, $4, $d1, $d2);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   130
	$match .= $found . $d2;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   131
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   132
    XML::XQL::parseError ("no $qname// closing delimiter found near '$q$d1'");
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   133
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   134
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   135
# To support nested delimiters in q{} and qq() strings
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   136
my %MatchingCloseDelim =
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   137
(
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   138
 '{' => '}',
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   139
 '(' => ')',
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   140
 '<' => '>',
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   141
 '[' => ']'
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   142
);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   143
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   144
sub Lexer 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   145
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   146
    my($parser)=shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   147
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   148
    exists($parser->YYData->{LINE})
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   149
	or $parser->YYData->{LINE} = 1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   150
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   151
    $parser->YYData->{INPUT}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   152
	or return('', undef);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   153
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   154
    print "Lexer input=[" . $parser->YYData->{INPUT} . "]\n"
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   155
	if $parser->{yydebug};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   156
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   157
    if ($Restricted)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   158
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   159
	# strip leading whitespace
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   160
	$parser->YYData->{INPUT} =~ s/^\s*//;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   161
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   162
    else
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   163
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   164
	# strip leading whitespace and comments
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   165
	$parser->YYData->{INPUT} =~ s/^(\s|#.*)*//;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   166
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   167
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   168
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   169
    for ($parser->YYData->{INPUT}) 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   170
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   171
	s#^"([^"]*)"##o	and return ('TEXT', $1);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   172
	s#^'([^']*)'##o	and return ('TEXT', $1);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   173
	
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   174
	if (not $Restricted)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   175
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   176
	    # Support q// and qq// string delimiters
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   177
	    for my $qname ('q', 'qq')
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   178
	    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   179
		my ($q) = $parser->{Query}->{$qname};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   180
		if (defined ($q) and s/^$q(\[\(\{\<#!=-\+|'":;\.,\?\/!@\%^\*)//)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   181
		{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   182
		    my ($d1, $d2) = ($1, $MatchingCloseDelim{$1});
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   183
		    my ($str);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   184
		    if (defined $d2)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   185
		    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   186
			($parser->YYData->{INPUT}, $str) = parse_q (
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   187
					$qname, $q, $_, $d1, $d2);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   188
		    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   189
		    else	# close delim is same open delim 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   190
		    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   191
			$d2 = $d1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   192
			s/([^$d2])*$d2// or XML::XQL::parseError (
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   193
			    "no $qname// closing delimiter found near '$q$d1'");
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   194
			$str = $1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   195
		    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   196
		    return ('TEXT', eval "$q$d1$str$d2");
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   197
		}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   198
	    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   199
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   200
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   201
	s/^(-?\d+\.(\d+)?)//		and return ('NUMBER', $1);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   202
	s/^(-?\d+)//			and return ('INTEGER', $1);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   203
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   204
	s/^(\$|\b)(i?(eq|ne|lt|le|gt|ge))\1(?=\W)//i
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   205
					and return ('COMPARE', "\L$2");
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   206
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   207
	s/^((\$|\b)(any|all|or|and|not|to|intersect)\2)(?=\W)//i
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   208
					and return ("\L$3", $1);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   209
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   210
  	s/^((\$|\b)union\2(?=\W)|\|)//i	and return ('UnionOp', $1);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   211
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   212
  	s/^(;;?)//			and return ('SeqOp', $1);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   213
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   214
	if (not $Restricted)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   215
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   216
	    s/^(=~|!~)//		and return ('MATCH', $1);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   217
	    s/^\$((no_)?match)\$//i
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   218
					and return ('MATCH', "\L$1");
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   219
	    s/^\$($ReXQLName)\$//o	and return ('COMPARE', $1);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   220
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   221
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   222
	s/^(=|!=|<|<=|>|>=)//		and return ('COMPARE', $1);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   223
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   224
	s!^(//|/|\(|\)|\.\.?|@|\!|\[|\]|\*|:|,)!!
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   225
					and return ($1, $1);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   226
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   227
 	s/^($ReXQLName)\s*\(//o
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   228
					and return ('XQLName_Paren', $1);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   229
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   230
	s/^($XML::RegExp::Name)//o	and return ('NCName', $1);	
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   231
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   232
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   233
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   234
#------ end Parser related stuff ----------------------------------------------
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   235
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   236
# Converts result from a Disjunction to a 0 or 1.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   237
# If it's a XML::XQL::Boolean, its value is returned.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   238
# If it's an empty list it returns 0.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   239
# If it's a node or a Text or Number, it returns 1.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   240
# If it's a list with 1 or more elements, it returns 1 if at least one
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   241
# element evaluates to 1 (with toBoolean)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   242
sub toBoolean	# static method
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   243
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   244
    my $arg = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   245
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   246
    my $type = ref ($arg);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   247
    if ($type eq "ARRAY")
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   248
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   249
	for my $n (@$arg)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   250
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   251
	    return 1 if toBoolean ($n);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   252
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   253
	return 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   254
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   255
    return $arg->xql_toBoolean;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   256
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   257
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   258
sub listContains
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   259
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   260
    my ($list, $x) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   261
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   262
#?? $n should be a PrimitiveType or an XML Node
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   263
    for my $y (@$list)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   264
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   265
#??	return 1 if $x == $y;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   266
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   267
	if (ref($x) eq ref($y))		# same object class
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   268
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   269
	    my ($src1, $src2) = ($x->xql_sourceNode, $y->xql_sourceNode);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   270
	    next if ((defined $src1 or defined $src2) and $src1 != $src2);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   271
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   272
	    return ($x == $y) if (UNIVERSAL::isa ($x, 'XML::XQL::Node'));
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   273
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   274
	    return 1 if $x->xql_eq ($y);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   275
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   276
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   277
    0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   278
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   279
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   280
sub toList
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   281
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   282
    my $r = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   283
    (ref ($r) eq "ARRAY") ? $r : [ $r ];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   284
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   285
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   286
# Prepare right hand side for a comparison, i.e.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   287
# turn it into a single value.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   288
# If it is a list with 2 or more values, it croaks.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   289
sub prepareRvalue
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   290
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   291
    my $r = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   292
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   293
    if (ref ($r) eq "ARRAY")
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   294
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   295
	# more than 1 value gives a runtime error (as per Joe Lapp)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   296
        croak "bad rvalue $r" if @$r > 1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   297
	$r = $r->[0];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   298
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   299
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   300
    if (ref ($r) and $r->isa ('XML::XQL::Node'))
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   301
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   302
	$r = $r->xql_value;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   303
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   304
    $r;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   305
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   306
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   307
sub trimSpace
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   308
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   309
    $_[0] =~ s/^\s+//;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   310
    $_[0] =~ s/\s+$//;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   311
    $_[0];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   312
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   313
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   314
# Assumption: max. 32768 (2**15 = 2**($BITS-1)) children (or attributes) per node
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   315
# Use setMaxChildren() to support larger offspring.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   316
my $BITS = 16;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   317
$LAST_SORT_KEY = (2 ** $BITS) - 1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   318
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   319
# Call with values: $max = 128 * (256**N), where N=0, 1, 2, ...
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   320
sub setMaxChildren
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   321
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   322
    my $max = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   323
    my $m = 128;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   324
    $BITS = 8;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   325
    while ($max > $m)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   326
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   327
	$m = $m * 256;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   328
	$BITS += 8;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   329
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   330
    $LAST_SORT_KEY = (2 ** $BITS) - 1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   331
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   332
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   333
sub createSortKey
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   334
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   335
    # $_[0] = parent sort key, $_[1] = child index, 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   336
    # $_[2] = 0 for attribute nodes, 1 for other node types
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   337
    my $vec = "";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   338
    vec ($vec, 0, $BITS) = $_[1];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   339
    vec ($vec, 7, 1) = $_[2] if $_[2];	# set leftmost bit (for non-attributes)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   340
    $_[0] . $vec;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   341
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   342
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   343
#--------------- Sorting source nodes ----------------------------------------
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   344
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   345
# Sort the list by 'document order' (as per the XQL spec.)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   346
# Values with an associated source node are sorted by the position of their 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   347
# source node in the XML document.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   348
# Values without a source node are placed at the end of the resulting list.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   349
# The source node of an Attribute node, is its (parent) Element node 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   350
# (per definition.) The source node of the other types of XML nodes, is itself.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   351
# The order for values with the same source node is undefined.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   352
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   353
sub sortDocOrder
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   354
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   355
#?? or should I just use: sort { $a->xql_sortKey cmp $b->xql_sortKey }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   356
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   357
    my $list = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   358
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   359
#print "before---\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   360
#for (@$list)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   361
#{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   362
#    print "key=" . keyStr($_->xql_sortKey) . " node=" . $_->getTagName . " id=" . $_->getAttribute('id') . "\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   363
#}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   364
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   365
    @$list =	map { $_->[1] }			# 3) extract nodes
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   366
		sort { $a->[0] cmp $b->[0] }	# 2) sort by sortKey
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   367
		map { [$_->xql_sortKey, $_] }	# 1) make [sortKey,node] records
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   368
		@$list;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   369
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   370
#print "after---\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   371
#for (@$list)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   372
#{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   373
#    print "key=" . keyStr($_->xql_sortKey) . " node=" . $_->getTagName . " id=" . $_->getAttribute('id') . "\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   374
#}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   375
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   376
    $list;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   377
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   378
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   379
# Converts sort key from createSortKey in human readable form
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   380
# For debugging only.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   381
sub keyStr
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   382
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   383
    my $key = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   384
    my $n = $BITS / 8;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   385
    my $bitn = 2 ** ($BITS - 1);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   386
    my $str;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   387
    for (my $i = 0; $i < length $key; $i += $n)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   388
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   389
	my $dig = substr ($key, $i, $n);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   390
	my $v = vec ($dig, 0, $BITS);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   391
	my $elem = 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   392
	if ($v >= $bitn)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   393
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   394
	    $v -= $bitn;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   395
	    $elem = 1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   396
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   397
	$str .= "/" if defined $str;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   398
	$str .= "@" unless $elem;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   399
	$str .= $v;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   400
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   401
    $str;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   402
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   403
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   404
sub isEmptyList
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   405
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   406
    my $list = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   407
    (ref ($list) eq "ARRAY") && (@$list == 0);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   408
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   409
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   410
# Used by Element and Attribute nodes
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   411
sub buildNameSpaceExpr
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   412
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   413
    my ($nameSpace, $name) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   414
    $name = ".*" if $name eq "*";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   415
    if (defined $nameSpace)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   416
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   417
	$nameSpace = ".*" if $nameSpace eq "*";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   418
	"^$nameSpace:$name\$";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   419
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   420
    else
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   421
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   422
	"^$name\$";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   423
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   424
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   425
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   426
sub prepareForCompare
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   427
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   428
    my ($left, $right) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   429
    my $leftType = $left->xql_primType;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   430
    if ($leftType == 0)		# Node
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   431
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   432
	$left = $left->xql_value;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   433
	$leftType = $left->xql_primType;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   434
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   435
    my $rightType = $right->xql_primType;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   436
    if ($rightType == 0)		# Node
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   437
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   438
	$right = $right->xql_value;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   439
	$rightType = $right->xql_primType;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   440
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   441
    # Note: reverse the order if $leftType < $rightType
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   442
    ($leftType < $rightType, $left, $right);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   443
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   444
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   445
sub xql_eq
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   446
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   447
    my ($left, $right, $ignoreCase) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   448
    my $reverse;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   449
    ($reverse, $left, $right) = prepareForCompare ($left, $right);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   450
    $reverse ? $right->xql_eq ($left, $ignoreCase)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   451
	     : $left->xql_eq ($right, $ignoreCase);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   452
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   453
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   454
sub xql_ne
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   455
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   456
    my ($left, $right, $ignoreCase) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   457
    my $reverse;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   458
    ($reverse, $left, $right) = prepareForCompare ($left, $right);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   459
    $reverse ? $right->xql_ne ($left, $ignoreCase)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   460
	     : $left->xql_ne ($right, $ignoreCase);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   461
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   462
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   463
sub xql_lt
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   464
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   465
    my ($left, $right, $ignoreCase) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   466
    my $reverse;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   467
    ($reverse, $left, $right) = prepareForCompare ($left, $right);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   468
    $reverse ? $right->xql_ge ($left, $ignoreCase)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   469
	     : $left->xql_lt ($right, $ignoreCase);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   470
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   471
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   472
sub xql_le
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   473
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   474
    my ($left, $right, $ignoreCase) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   475
    my $reverse;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   476
    ($reverse, $left, $right) = prepareForCompare ($left, $right);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   477
    $reverse ? $right->xql_gt ($left, $ignoreCase)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   478
	     : $left->xql_le ($right, $ignoreCase);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   479
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   480
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   481
sub xql_gt
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   482
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   483
    my ($left, $right, $ignoreCase) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   484
    my $reverse;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   485
    ($reverse, $left, $right) = prepareForCompare ($left, $right);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   486
    $reverse ? $right->xql_le ($left, $ignoreCase)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   487
	     : $left->xql_gt ($right, $ignoreCase);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   488
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   489
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   490
sub xql_ge
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   491
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   492
    my ($left, $right, $ignoreCase) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   493
    my $reverse;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   494
    ($reverse, $left, $right) = prepareForCompare ($left, $right);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   495
    $reverse ? $right->xql_lt ($left, $ignoreCase)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   496
	     : $left->xql_ge ($right, $ignoreCase);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   497
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   498
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   499
sub xql_ieq { xql_eq (@_, 1); }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   500
sub xql_ine { xql_ne (@_, 1); }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   501
sub xql_ilt { xql_lt (@_, 1); }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   502
sub xql_igt { xql_gt (@_, 1); }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   503
sub xql_ige { xql_ge (@_, 1); }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   504
sub xql_ile { xql_le (@_, 1); }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   505
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   506
sub tput
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   507
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   508
    # Let me know if I need to add other systems for which 'tput' is not 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   509
    # available.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   510
    if ($^O =~ /Win|MacOS/)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   511
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   512
	return undef;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   513
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   514
    else
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   515
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   516
	my $c = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   517
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   518
	# tput is only available on Unix systems.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   519
	# Calling `tput ...` on Windows generates warning messages
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   520
	# that can not be suppressed.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   521
	return `tput $c`;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   522
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   523
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   524
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   525
# Underline the query subexpression that fails (if tput exists)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   526
$ContextStart = tput ('smul') || ">>";	# smul: underline on
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   527
$ContextEnd = tput ('rmul') || "<<";	# rmul: underline off
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   528
# Used for making the significant keyword of a subexpression bold, e.g. "$and$"
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   529
$BoldOn = tput ('bold') || "";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   530
$BoldOff = tput ('rmul') . tput ('smul') || "";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   531
# rmul reverts the string back to normal text, smul makes it underlined again, 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   532
# so the rest of the subexpresion will be underlined.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   533
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   534
sub setErrorContextDelimiters
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   535
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   536
    ($ContextStart, $ContextEnd, $BoldOn, $BoldOff) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   537
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   538
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   539
sub delim
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   540
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   541
    my ($str, $node, $contextNode) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   542
    if ($node == $contextNode)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   543
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   544
	$str =~ s/\016([^\017]*)\017/$BoldOn$1$BoldOff/g;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   545
	"$ContextStart$str$ContextEnd";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   546
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   547
    else
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   548
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   549
	$str =~ s/\016([^\017]*)\017/$1/g;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   550
	$str;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   551
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   552
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   553
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   554
sub bold
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   555
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   556
    my $x = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   557
    "\016$x\017";	# arbitrary ASCII codes
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   558
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   559
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   560
sub parseError
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   561
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   562
    my ($msg) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   563
    print STDERR $msg . "\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   564
    croak $msg;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   565
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   566
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   567
# Builtin XQL functions (may not appear after Bang "!")
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   568
%Func = 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   569
(
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   570
 ancestor	=> \&XML::XQL::Func::ancestor,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   571
 attribute	=> \&XML::XQL::Func::attribute,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   572
 comment	=> \&XML::XQL::Func::comment,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   573
 element	=> \&XML::XQL::Func::element,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   574
 id		=> \&XML::XQL::Func::id,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   575
 node		=> \&XML::XQL::Func::node,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   576
 pi		=> \&XML::XQL::Func::pi,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   577
 textNode	=> \&XML::XQL::Func::textNode,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   578
 true		=> \&XML::XQL::Func::true,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   579
 false		=> \&XML::XQL::Func::false,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   580
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   581
# NOTE: date() is added with:   use XML::XQL::Date;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   582
);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   583
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   584
# Builtin XQL methods (may appear after Bang "!")
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   585
%Method = 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   586
(
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   587
 baseName	=> \&XML::XQL::Func::baseName,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   588
 count		=> \&XML::XQL::Func::count,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   589
 end		=> \&XML::XQL::Func::end,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   590
 'index'	=> \&XML::XQL::Func::xql_index,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   591
 namespace	=> \&XML::XQL::Func::namespace,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   592
 nodeName	=> \&XML::XQL::Func::nodeName,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   593
 nodeType	=> \&XML::XQL::Func::nodeType,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   594
 nodeTypeString	=> \&XML::XQL::Func::nodeTypeString,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   595
 prefix		=> \&XML::XQL::Func::prefix,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   596
 text		=> \&XML::XQL::Func::text,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   597
 rawText	=> \&XML::XQL::Func::rawText,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   598
 value		=> \&XML::XQL::Func::value,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   599
);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   600
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   601
# Number of arguments for builtin XQL functions:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   602
# Value is either an integer or a range. Value is 0 if not specified.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   603
# Range syntax:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   604
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   605
#  range ::= '[' start ',' end [ ',' start ',' end ]*  ']' 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   606
#  start ::= INTEGER
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   607
#  end   ::= INTEGER | '-1'    ('-1' means: "or more")
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   608
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   609
# Example: [2, 4, 7, 7, 10, -1] means (2,3,4,7,10,11,...)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   610
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   611
%FuncArgCount =
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   612
(
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   613
 ancestor	=> 1,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   614
 attribute	=> [0,1],
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   615
 count		=> [0,1],
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   616
# date		=> 1,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   617
 element	=> [0,1],
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   618
 id		=> 1,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   619
 text		=> [0,1],
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   620
 rawText	=> [0,1],
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   621
);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   622
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   623
%AllowedOutsideSubquery = 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   624
(
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   625
 ancestor	=> 1,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   626
 attribute	=> 1,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   627
 comment	=> 1,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   628
 element	=> 1,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   629
 id		=> 1,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   630
 node		=> 1,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   631
 pi		=> 1,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   632
 textNode	=> 1,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   633
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   634
#?? what about subst etc.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   635
);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   636
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   637
# Functions that always return the same thing if their arguments are constant
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   638
%ConstFunc =
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   639
(
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   640
 true		=> 1,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   641
 false		=> 1,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   642
# date		=> 1,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   643
);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   644
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   645
%ExpandedType =
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   646
(
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   647
 "boolean"	=> "XML::XQL::Boolean",
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   648
 "text"		=> "XML::XQL::Text",
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   649
 "number"	=> "XML::XQL::Number",
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   650
 "date"		=> "XML::XQL::Date",
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   651
 "node"		=> "XML::XQL::Node",
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   652
);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   653
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   654
sub expandType
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   655
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   656
    my ($type) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   657
    # Expand "number" to "XML::XQL::Number" etc.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   658
    my $expanded = $ExpandedType{"\L$type"};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   659
    defined $expanded ? $expanded : $type;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   660
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   661
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   662
sub defineExpandedTypes
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   663
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   664
    my (%args) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   665
    while (my ($key, $val) = each %args)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   666
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   667
	# Convert keys to lowercase
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   668
	$ExpandedType{"\L$key"} = $val;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   669
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   670
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   671
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   672
sub generateFunction
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   673
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   674
    my ($name, $funcName, $returnType, $argCount, $allowedOutsideSubquery, 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   675
	$const, $queryArg) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   676
    $argCount = 0 unless defined $argCount;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   677
    $allowedOutsideSubquery = 1 unless defined $allowedOutsideSubquery;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   678
    $const = 0 unless defined $const;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   679
    $queryArg = 0 unless defined $queryArg;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   680
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   681
    $returnType = expandType ($returnType);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   682
    my $wrapperName = "xql_wrap_$name";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   683
    $wrapperName =~ s/\W/_/g;		# replace colons etc.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   684
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   685
    my $func;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   686
    my $code = <<END_CODE;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   687
sub $wrapperName {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   688
 my (\$context, \$list, \@arg) = \@_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   689
 for my \$i (0 .. \$#arg)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   690
 {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   691
  if (\$i == $queryArg)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   692
  {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   693
   \$arg[\$i] = XML::XQL::toList (\$arg[\$i]->solve (\$context, \$list));
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   694
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   695
  else
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   696
  {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   697
   \$arg[\$i] = XML::XQL::prepareRvalue (\$arg[\$i]->solve (\$context, \$list));
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   698
   return [] if XML::XQL::isEmptyList (\$arg[\$i]);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   699
   \$arg[\$i] = \$arg[\$i]->xql_toString;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   700
  }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   701
 }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   702
END_CODE
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   703
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   704
    if (ref ($argCount) eq "ARRAY" && @$argCount == 2 && 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   705
	$argCount->[0] == $argCount->[1])
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   706
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   707
        $argCount = $argCount->[0];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   708
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   709
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   710
    if ($queryArg != -1)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   711
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   712
	$code .=<<END_CODE;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   713
 my \@result = ();
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   714
 my \@qp = \@{\$arg[$queryArg]};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   715
 for (my \$k = 0; \$k < \@qp; \$k++)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   716
 {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   717
  \$arg[$queryArg] = \$qp[\$k]->xql_toString;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   718
END_CODE
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   719
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   720
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   721
    if (ref ($argCount) ne "ARRAY")
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   722
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   723
        $code .= " my \$result = $funcName (";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   724
	for my $i (0 .. $argCount-1)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   725
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   726
	    $code .= ", " if $i;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   727
	    $code .= "\$arg[$i]";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   728
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   729
	$code .= ");\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   730
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   731
    elsif (@$argCount == 2)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   732
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   733
	my ($start, $end) = ($argCount->[0], $argCount->[1]);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   734
	if ($end == -1)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   735
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   736
            $code .= " my \$result = $funcName (";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   737
	    for my $i (0 .. ($start - 1))
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   738
	    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   739
		$code .= ", " if $i;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   740
		$code .= "\$arg[$i]";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   741
	    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   742
	    $code .= ", \@arg[" . $start . " .. \$#arg]);\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   743
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   744
	else
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   745
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   746
	    $code .= " my \$n = \@arg;\n my \$result;\n ";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   747
	    for my $j ($argCount->[0] .. $argCount->[1])
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   748
	    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   749
		$code .= " els" unless $j == $argCount->[0];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   750
		$code .= ($j == $argCount->[1] ? "e\n" : 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   751
			"if (\$n == $j)\n");
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   752
		$code .= " {\n  \$result = $funcName (";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   753
		for my $i (0 .. $j-1)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   754
		{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   755
		    $code .= ", " if $i;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   756
		    $code .= "\$arg[$i]";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   757
		}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   758
		$code .= ");\n }\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   759
	    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   760
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   761
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   762
    else	 #?? what now...
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   763
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   764
	$code .= " my \$result = $funcName (\@arg);\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   765
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   766
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   767
    if ($returnType eq "*")	# return result as is
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   768
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   769
	$code .= " \$result = [] unless defined \$result;\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   770
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   771
    else
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   772
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   773
	$code .= " \$result = defined \$result ? new $returnType (\$result) : [];\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   774
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   775
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   776
    if ($queryArg == -1)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   777
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   778
	$code .= " \$result;\n}\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   779
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   780
    else
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   781
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   782
        $code .= "  push \@result, \$result;\n }\n \\\@result;\n}\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   783
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   784
    $code .= "\$func = \\\&$wrapperName;";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   785
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   786
#print "CODE=$code\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   787
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   788
    eval "$code";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   789
    if ($@) { croak "generateFunction failed for $funcName: $@\n"; }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   790
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   791
    defineFunction ($name, $func, $argCount, 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   792
		    $allowedOutsideSubquery, $const);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   793
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   794
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   795
sub defineFunction
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   796
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   797
    my ($name, $func, $argCount, $allowedOutside, $const) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   798
    $Func{$name} = $func;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   799
    $FuncArgCount{$name} = $argCount;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   800
    $AllowedOutsideSubquery{$name} = 1 if $allowedOutside;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   801
    $ConstFunc{$name} = $const;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   802
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   803
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   804
sub defineMethod
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   805
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   806
    my ($name, $func, $argCount, $allowedOutside) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   807
    $Method{$name} = $func;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   808
    $FuncArgCount{$name} = $argCount;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   809
    $AllowedOutsideSubquery{$name} = 1 if $allowedOutside;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   810
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   811
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   812
%CompareOper =
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   813
(
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   814
 'eq' => \&XML::XQL::xql_eq,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   815
 'ne' => \&XML::XQL::xql_ne,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   816
 'le' => \&XML::XQL::xql_le,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   817
 'ge' => \&XML::XQL::xql_ge,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   818
 'gt' => \&XML::XQL::xql_gt,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   819
 'lt' => \&XML::XQL::xql_lt,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   820
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   821
 'ieq' => \&XML::XQL::xql_ieq,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   822
 'ine' => \&XML::XQL::xql_ine,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   823
 'ile' => \&XML::XQL::xql_ile,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   824
 'ige' => \&XML::XQL::xql_ige,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   825
 'igt' => \&XML::XQL::xql_igt,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   826
 'ilt' => \&XML::XQL::xql_ilt,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   827
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   828
 '='  => \&XML::XQL::xql_eq,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   829
 '!=' => \&XML::XQL::xql_ne,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   830
 '>'  => \&XML::XQL::xql_gt,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   831
 '>=' => \&XML::XQL::xql_ge,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   832
 '<'  => \&XML::XQL::xql_lt,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   833
 '<=' => \&XML::XQL::xql_le,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   834
);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   835
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   836
sub defineComparisonOperators
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   837
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   838
    my (%args) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   839
    %CompareOper = (%CompareOper, %args);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   840
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   841
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   842
sub defineTokenQ
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   843
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   844
    $Token_q = $_[0];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   845
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   846
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   847
sub defineTokenQQ
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   848
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   849
    $Token_qq = $_[0];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   850
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   851
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   852
my %ElementValueType = ();
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   853
my $ElementValueTypeCount = 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   854
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   855
sub elementValue
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   856
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   857
    my ($elem) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   858
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   859
#?? raw text/recursive ?
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   860
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   861
    return new XML::XQL::Text ($elem->xql_text, $elem) 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   862
	if $ElementValueTypeCount == 0;   # user hasn't defined any types
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   863
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   864
    my $tagName = $elem->xql_nodeName;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   865
    my $func = $ElementValueType{$tagName};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   866
    return new XML::XQL::Text ($elem->xql_text, $elem) unless defined $func;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   867
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   868
    &$func ($elem, $tagName); 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   869
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   870
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   871
sub defineElementValueConvertor
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   872
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   873
    my ($elemTagName, $func) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   874
    my $prev = defined $ElementValueType{$elemTagName};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   875
    $ElementValueType{$elemTagName} = $func;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   876
    if (defined $func != $prev)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   877
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   878
	defined $func ? $ElementValueTypeCount++ : $ElementValueTypeCount--;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   879
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   880
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   881
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   882
my %AttrValueType = ();
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   883
my $AttrValueTypeCount = 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   884
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   885
sub attrValue
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   886
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   887
    my ($attr) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   888
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   889
#?? raw text/recursive ?
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   890
    return new XML::XQL::Text ($attr->xql_text, $attr) 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   891
	if $AttrValueTypeCount == 0;    # user hasn't defined any types
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   892
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   893
    my $elem = $attr->xql_parent->xql_nodeName;    
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   894
    my $attrName = $attr->xql_nodeName;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   895
    my $func = $AttrValueType{"$elem $attrName"};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   896
    
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   897
    if (not defined $func)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   898
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   899
	$elem = "*";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   900
	$func = $AttrValueType{"$elem $attrName"};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   901
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   902
    return new XML::XQL::Text ($attr->xql_text, $attr) unless defined $func;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   903
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   904
    &$func ($attr, $attrName, $elem);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   905
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   906
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   907
sub defineAttrValueConvertor
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   908
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   909
    my ($elemTagName, $attrName, $type) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   910
    my $both = "$elemTagName $attrName";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   911
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   912
    my $prev = defined $AttrValueType{$both};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   913
    $AttrValueType{$both} = $type;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   914
    if (defined $type != $prev)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   915
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   916
	defined $type ? $AttrValueTypeCount++ : $AttrValueTypeCount--;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   917
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   918
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   919
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   920
#=== debug
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   921
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   922
sub exception
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   923
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   924
    my ($ex) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   925
    print "Exception: $ex\n" if $ex;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   926
    $ex;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   927
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   928
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   929
sub d
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   930
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   931
    my $n = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   932
    my $type = ref $n;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   933
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   934
    if ($type eq "ARRAY")
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   935
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   936
	my $str = "";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   937
	for my $i (@$n)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   938
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   939
	    $str .= ", " unless $str eq "";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   940
	    $str .= d ($i);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   941
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   942
	return "[$str]";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   943
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   944
    elsif ($type eq "HASH")
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   945
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   946
	my $str = "";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   947
	while (my ($key, $val) = %$n)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   948
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   949
	    $str .= ", " unless $str eq "";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   950
	    $str .= $key . " => " . d ($val);    
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   951
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   952
	return "{$str}";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   953
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   954
    elsif ($type)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   955
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   956
	return $n->xql_contextString if ($n->isa ('XML::XQL::Operator'));
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   957
	return "${type}\[" . $n->xql_toString . "]" if $n->isa ('XML::XQL::PrimitiveType');
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   958
#	return "${type}\[" . $n->toString . "]" if $n->isa ('XML::DOM::Element');
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   959
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   960
    $n;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   961
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   962
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   963
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   964
package XML::XQL::Query;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   965
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   966
use Carp;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   967
use XML::XQL::Parser;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   968
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   969
use vars qw( %Func %FuncArgCount );
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   970
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   971
my $parser = new XML::XQL::Parser;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   972
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   973
# This is passed as 'yyerror' to YYParse
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   974
sub Error 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   975
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   976
    my($parser) = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   977
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   978
    print STDERR "Error in Query Expression near: " . $parser->YYData->{INPUT} . "\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   979
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   980
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   981
sub defineFunction
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   982
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   983
    my ($self, $name, $func, $argCount, $allowedOutside, $const) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   984
    $self->{Func}->{$name} = $func;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   985
    $self->{FuncArgCount}->{$name} = $argCount;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   986
    $self->{AllowedOutsideSubquery}->{$name} = 1 if $allowedOutside;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   987
    $self->{ConstFunc} = $const;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   988
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   989
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   990
sub defineMethod
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   991
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   992
    my ($self, $name, $func, $argCount, $allowedOutside) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   993
    $self->{Method}->{$name} = $func;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   994
    $self->{FuncArgCount}->{$name} = $argCount;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   995
    $self->{AllowedOutsideSubquery}->{$name} = 1 if $allowedOutside;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   996
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   997
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   998
sub defineComparisonOperators
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
   999
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1000
    my ($self, %args) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1001
    $self->{CompareOper} = \%args;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1002
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1003
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1004
sub defineTokenQ
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1005
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1006
    $_[0]->{'q'} = $_[1];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1007
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1008
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1009
sub defineTokenQQ
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1010
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1011
    $_[0]->{'qq'} = $_[1];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1012
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1013
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1014
sub new
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1015
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1016
    my ($class, %args) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1017
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1018
    croak "no Expr specified" unless defined $args{Expr};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1019
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1020
    my $self = bless \%args, $class;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1021
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1022
    my $error = $self->{'Error'} || \&XML::XQL::Query::Error;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1023
    my $debug = defined ($self->{Debug}) ? $self->{Debug} : 0;   # 0x17;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1024
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1025
    $self->{'q'} = $XML::XQL::Token_q unless exists $self->{'q'};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1026
    $self->{'qq'} = $XML::XQL::Token_qq unless exists $self->{'qq'};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1027
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1028
    # Invoke the query expression parser
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1029
    $parser->YYData->{INPUT} = $self->{Expr};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1030
    $parser->{Query} = $self;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1031
    $self->{Tree} = $parser->YYParse (yylex => \&XML::XQL::Lexer,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1032
				      yyerror => $error, 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1033
				      yydebug => $debug);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1034
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1035
    # Nothing but whitespace should be left over
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1036
    if ($parser->YYData->{INPUT} !~ /^\s*$/)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1037
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1038
	XML::XQL::parseError ("Error when parsing expression. Unexpected characters at end of expression [" . $parser->YYData->{INPUT} . "]")
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1039
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1040
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1041
    XML::XQL::parseError ("Error when parsing expression")
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1042
	unless defined $self->{Tree};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1043
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1044
    $self->{Tree}->{Query} = $self;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1045
    $self->{Tree}->xql_check (0, 0);	# inSubQuery=0, inParam=0
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1046
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1047
    print "Expression parsed successfully\n" if $debug;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1048
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1049
    $self;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1050
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1051
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1052
sub dispose
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1053
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1054
    my $self = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1055
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1056
    undef $self->{Tree}->{Query};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1057
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1058
    $self->{Tree}->dispose;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1059
    delete $self->{Tree};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1060
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1061
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1062
sub isNodeQuery
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1063
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1064
    $_[0]->{NodeQuery};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1065
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1066
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1067
sub solve
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1068
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1069
    my ($self, @list) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1070
    my $context = undef;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1071
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1072
    # clear cached "once" values
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1073
    $self->{Tree}->xql_prepCache;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1074
    my $result = $self->{Tree}->solve ($context, \@list);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1075
    ref ($result) eq "ARRAY" ? @$result : ($result);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1076
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1077
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1078
sub toString
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1079
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1080
    $_[0]->{Expr};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1081
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1082
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1083
sub toDOM
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1084
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1085
    my ($self, $doc) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1086
    my $root = $doc->createElement ("XQL");
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1087
    $doc->appendChild ($root);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1088
    $root->appendChild ($self->{Tree}->xql_toDOM ($doc));
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1089
    $doc;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1090
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1091
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1092
sub findComparisonOperator
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1093
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1094
    my ($self, $name) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1095
    my $cmp;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1096
    if (exists $self->{CompareOper}->{$name})
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1097
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1098
	$cmp = $self->{CompareOper}->{$name};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1099
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1100
    else
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1101
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1102
	$cmp = $XML::XQL::CompareOper{$name};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1103
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1104
    if (not defined $cmp)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1105
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1106
        XML::XQL::parseError ("undefined comparison operator '$name'");
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1107
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1108
    $cmp;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1109
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1110
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1111
# Return function pointer. Croak if wrong number of arguments.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1112
sub findFunctionOrMethod
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1113
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1114
    my ($self, $name, $args) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1115
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1116
    my $func;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1117
    my $type = "function";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1118
    if (exists $self->{Func}->{$name})
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1119
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1120
	$func = $self->{Func}->{$name};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1121
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1122
    elsif (exists $self->{Method}->{$name})
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1123
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1124
	$func = $self->{Method}->{$name};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1125
	$type = "method";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1126
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1127
    elsif (defined $XML::XQL::Func{$name})
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1128
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1129
	$func = $XML::XQL::Func{$name};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1130
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1131
    elsif (defined $XML::XQL::Method{$name})
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1132
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1133
	$func = $XML::XQL::Method{$name};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1134
	$type = "method";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1135
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1136
    elsif (not $XML::XQL::Restricted)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1137
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1138
        $func = XML::XQL::generatePerlWrapper ($name);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1139
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1140
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1141
    XML::XQL::parseError ("undefined function/method '$name' in query '" . 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1142
		$self->toString . "'")
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1143
        unless defined &$func;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1144
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1145
    my $funcArgCount = $self->{FuncArgCount}->{$name} 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1146
			|| $XML::XQL::FuncArgCount{$name} || 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1147
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1148
    # Check number of args
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1149
    my $nargs = @$args;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1150
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1151
#print "$args " . XML::XQL::d($args) . "\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1152
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1153
    my $ok = 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1154
    if (ref ($funcArgCount) eq "ARRAY")
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1155
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1156
	my $i = 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1157
	my $n = @$funcArgCount;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1158
	while ($i < $n)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1159
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1160
	    my $s = $funcArgCount->[$i++];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1161
	    my $e = $funcArgCount->[$i++] || $s;	# same as $s if odd #args
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1162
	    if ($nargs >= $s && ($e == -1 || $nargs <= $e))
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1163
	    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1164
		$ok = 1;	# found it
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1165
		last;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1166
	    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1167
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1168
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1169
    else
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1170
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1171
	$ok = ($nargs eq $funcArgCount);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1172
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1173
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1174
    XML::XQL::parseError ("wrong number of args ($nargs) for $type $name in query '" .
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1175
	    $self->toString . "', it should be " . XML::XQL::d($funcArgCount))
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1176
	if not $ok;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1177
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1178
    return ($func, $type);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1179
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1180
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1181
sub isAllowedOutsideSubquery
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1182
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1183
    my ($self, $funcName) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1184
    my ($ok) = $self->{AllowedOutsideSubquery}->{$funcName};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1185
    return $ok if defined $ok;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1186
    $XML::XQL::AllowedOutsideSubquery{$funcName};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1187
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1188
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1189
package XML::XQL::Operator;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1190
use fields qw{ Left Right Parent };
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1191
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1192
sub new
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1193
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1194
    my ($class, %attr) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1195
    my $self = bless \%attr, $class;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1196
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1197
    $self->{Left}->setParent ($self) if defined $self->{Left};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1198
    $self->{Right}->setParent ($self) if defined $self->{Right};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1199
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1200
    $self;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1201
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1202
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1203
sub dispose
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1204
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1205
    my $self = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1206
    if (defined ($self->{Left}))
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1207
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1208
	$self->{Left}->dispose;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1209
	undef $self->{Left};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1210
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1211
    if (defined ($self->{Right}))
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1212
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1213
	$self->{Right}->dispose;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1214
	undef $self->{Right};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1215
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1216
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1217
    undef $self->{Parent};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1218
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1219
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1220
sub xql_check
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1221
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1222
    my ($self, $inSubQuery, $inParam) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1223
    $self->{Left}->xql_check ($inSubQuery, $inParam);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1224
    $self->{Right}->xql_check ($inSubQuery, $inParam) if defined $self->{Right};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1225
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1226
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1227
sub xql_prepCache
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1228
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1229
    my ($self) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1230
    $self->{Left}->xql_prepCache;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1231
    $self->{Right}->xql_prepCache if defined $self->{Right};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1232
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1233
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1234
sub xql_toDOM
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1235
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1236
    my ($self, $doc) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1237
    my $name = ref $self;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1238
    $name =~ s/.*:://;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1239
    my $elem = $doc->createElement ($name);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1240
    if (defined $self->{Left})
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1241
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1242
	my $left = $doc->createElement ("left");
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1243
	$elem->appendChild ($left);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1244
	$left->appendChild ($self->{Left}->xql_toDOM ($doc));
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1245
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1246
    if (defined $self->{Right})
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1247
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1248
	my $right = $doc->createElement ("right");
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1249
	$elem->appendChild ($right);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1250
	$right->appendChild ($self->{Right}->xql_toDOM ($doc));
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1251
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1252
    $elem;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1253
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1254
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1255
sub isConstant
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1256
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1257
    0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1258
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1259
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1260
# Overriden by Union and Path operators
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1261
sub mustSort
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1262
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1263
    0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1264
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1265
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1266
sub setParent
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1267
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1268
    $_[0]->{Parent} = $_[1];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1269
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1270
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1271
sub warning
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1272
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1273
    my ($self, $msg) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1274
    print STDERR "WARNING: $msg";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1275
    print STDERR "         Context: " . $self->toContextString . "\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1276
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1277
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1278
sub root
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1279
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1280
    my ($self) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1281
    my $top = $self;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1282
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1283
    while (defined ($top->{Parent}))
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1284
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1285
	$top = $top->{Parent};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1286
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1287
    $top;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1288
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1289
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1290
sub query
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1291
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1292
    $_[0]->root->{Query};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1293
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1294
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1295
sub toContextString
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1296
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1297
    my ($self) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1298
    $self->root->xql_contextString ($self);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1299
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1300
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1301
sub debugString
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1302
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1303
    my ($self) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1304
    my $str = "[" . ref($self);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1305
    while (my ($key, $val) = each %$self)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1306
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1307
	$str .= "$key=>" . XML::XQL::d($val);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1308
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1309
    $str . "]";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1310
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1311
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1312
sub verbose
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1313
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1314
    my ($self, $str, $list) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1315
#    print STDERR "$self - $str: " . XML::XQL::d($list) . "\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1316
    $list;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1317
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1318
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1319
package XML::XQL::Root;		# "/" at start of XQL expression
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1320
use base 'XML::XQL::Operator';	# L -> L
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1321
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1322
sub solve
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1323
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1324
    my ($self, $context, $list) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1325
    return [] if (@$list < 1);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1326
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1327
#?? what if first value is not a XML::XQL::Node? should we try the second one?
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1328
    [$list->[0]->xql_document];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1329
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1330
#?? add isOnce here?
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1331
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1332
sub xql_check
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1333
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1334
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1335
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1336
sub xql_prepCache
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1337
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1338
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1339
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1340
sub xql_contextString
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1341
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1342
    XML::XQL::delim ("/", @_);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1343
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1344
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1345
package XML::XQL::Path;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1346
use base 'XML::XQL::Operator';	# L -> L
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1347
use fields qw{ PathOp };
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1348
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1349
sub new
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1350
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1351
    my ($class, %arg) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1352
    my $self = bless \%arg, $class;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1353
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1354
    $self->{Left} ||= new XML::XQL::Root;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1355
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1356
    $self->{Left}->setParent ($self);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1357
    $self->{Right}->setParent ($self);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1358
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1359
    $self;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1360
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1361
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1362
sub solve
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1363
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1364
    my ($self, $context, $list) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1365
    $list = $self->{Left}->solve ($context, $list);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1366
    $self->verbose ("left", $list);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1367
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1368
    return $list if @$list < 1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1369
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1370
    if ($self->{PathOp} eq '/') 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1371
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1372
	$self->verbose ("result", $self->{Right}->solve ($context, $list));
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1373
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1374
    else	# recurse "//"
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1375
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1376
	my $new_list = [];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1377
	my $n = @$list;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1378
        NODE: for (my $i = 0; $i < $n; $i++)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1379
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1380
	    my $node = $list->[$i];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1381
	    # Node must be an Element or must be allowed to contain Elements
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1382
	    # i.e. must be an Element or a Document 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1383
	    # (DocumentFragment is not expected here)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1384
	    my $nodeType = $node->xql_nodeType;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1385
	    next NODE unless ($nodeType == 1 || $nodeType == 9);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1386
	    
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1387
	    # Skip the node if one of its ancestors is part of the input $list
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1388
	    # (and therefore already processed)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1389
	    my $parent = $node->xql_parent;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1390
	    while (defined $parent)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1391
	    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1392
		for (my $j = $i - 1; $j >= 0; $j--)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1393
		{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1394
		    next NODE if ($parent == $list->[$j]);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1395
		}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1396
		$parent = $parent->xql_parent;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1397
	    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1398
	    recurse ($node, $new_list);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1399
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1400
	
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1401
	my $results = $self->{Right}->solve ($context, $new_list);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1402
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1403
	# Sort the result list unless the parent Operator will sort
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1404
	my $parent = $self->{Parent};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1405
	XML::XQL::sortDocOrder ($results) 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1406
		unless defined ($parent) and $parent->mustSort;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1407
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1408
	$self->verbose ("result //", $results);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1409
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1410
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1411
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1412
sub mustSort
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1413
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1414
    $_[0]->{PathOp} eq '//'; 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1415
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1416
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1417
sub recurse
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1418
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1419
    my ($node, $list) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1420
    push @$list, $node;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1421
    for my $kid (@{$node->xql_element})
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1422
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1423
	recurse ($kid, $list);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1424
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1425
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1426
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1427
sub xql_contextString
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1428
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1429
    my $self = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1430
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1431
    my $str = $self->{Left}->isa ('XML::XQL::Root') ? 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1432
	"" : $self->{Left}->xql_contextString (@_);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1433
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1434
    XML::XQL::delim ($str . XML::XQL::bold($self->{PathOp}) . 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1435
		     $self->{Right}->xql_contextString (@_), $self, @_);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1436
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1437
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1438
sub xql_toDOM
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1439
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1440
    my ($self, $doc) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1441
    my $elem = $self->SUPER::xql_toDOM ($doc);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1442
    $elem->setAttribute ("pathOp", $self->{PathOp});
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1443
    $elem;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1444
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1445
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1446
package XML::XQL::Sequence;		# "elem;elem" or "elem;;elem"
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1447
use base 'XML::XQL::Operator';	# L -> L
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1448
use fields qw{ Oper };
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1449
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1450
# See "The Design of XQL" by Jonathan Robie
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1451
# <URL:http://www.texcel.no/whitepapers/xql-design.html>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1452
# for definition of Sequence operators.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1453
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1454
# Note that the "naive" implementation slows things down quite a bit here...
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1455
sub solve
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1456
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1457
    my ($self, $context, $list) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1458
    my $left = $self->{Left}->solve ($context, $list);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1459
    $self->verbose ("left", $left);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1460
    return [] unless @$left;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1461
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1462
    my $right = $self->{Right}->solve ($context, $list);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1463
    $self->verbose ("right", $right);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1464
    return [] unless @$right;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1465
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1466
    my @result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1467
    if ($self->{Oper} eq ';')	# immediately precedes
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1468
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1469
	my %hleft; @hleft{@$left} = ();	# initialize all values to undef
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1470
	my %pushed;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1471
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1472
	for my $r (@$right)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1473
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1474
	    # Find previous sibling that is not a text node that has only 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1475
	    # whitespace that can be ignored (because xml:space=preserve)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1476
	    my $prev = $r->xql_prevNonWS;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1477
	    # $prev must be defined and must exist in $left
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1478
	    next unless $prev and exists $hleft{$prev};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1479
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1480
	    # Filter duplicates (no need to sort afterwards)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1481
	    push @result, $prev unless $pushed{$prev}++;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1482
	    push @result, $r unless $pushed{$r}++;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1483
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1484
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1485
    else	# oper eq ';;' (i.e. precedes)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1486
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1487
	my %pushed;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1488
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1489
	for my $r (@$right)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1490
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1491
	    for my $l (@$left)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1492
	    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1493
		# If left node precedes right node, add them
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1494
		if ($l->xql_sortKey lt $r->xql_sortKey)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1495
		{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1496
		    # Filter duplicates
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1497
		    push @result, $l unless $pushed{$l}++;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1498
		    push @result, $r unless $pushed{$r}++;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1499
		}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1500
	    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1501
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1502
#?? optimize - left & right are already sorted...
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1503
	    # sort in document order
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1504
	    XML::XQL::sortDocOrder (\@result) if @result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1505
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1506
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1507
    \@result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1508
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1509
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1510
sub xql_contextString
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1511
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1512
    my $self = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1513
    XML::XQL::delim ($self->{Left}->xql_contextString (@_) . 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1514
		     XML::XQL::bold($self->{Oper}) . 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1515
		     $self->{Right}->xql_contextString (@_), $self, @_);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1516
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1517
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1518
package XML::XQL::Current;		# "."
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1519
use base 'XML::XQL::Operator';	# L -> L
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1520
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1521
sub xql_check
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1522
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1523
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1524
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1525
sub xql_prepCache
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1526
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1527
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1528
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1529
sub solve
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1530
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1531
    my ($self, $context, $list) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1532
    $list;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1533
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1534
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1535
sub xql_contextString
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1536
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1537
    XML::XQL::delim (".", @_);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1538
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1539
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1540
package XML::XQL::Parent;		# ".."
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1541
use base 'XML::XQL::Operator';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1542
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1543
sub xql_check
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1544
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1545
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1546
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1547
sub xql_prepCache
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1548
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1549
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1550
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1551
sub solve
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1552
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1553
    my ($self, $context, $list) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1554
    my @result = ();
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1555
    for my $node (@$list)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1556
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1557
	push @result, $node->xql_parent;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1558
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1559
    \@result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1560
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1561
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1562
sub xql_contextString
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1563
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1564
    XML::XQL::delim ("..", @_);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1565
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1566
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1567
package XML::XQL::Element;		# "elem"
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1568
use base 'XML::XQL::Operator';		# L -> L
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1569
use fields qw{ Name NameSpace Expr };
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1570
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1571
sub new
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1572
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1573
    my ($class, %args) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1574
    if (not defined ($args{NameSpace}))
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1575
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1576
	if ($args{Name} eq "*")
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1577
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1578
	    return bless \%args, 'XML::XQL::AllElements';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1579
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1580
	else
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1581
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1582
	    return bless \%args, 'XML::XQL::SimpleElement';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1583
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1584
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1585
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1586
    $args{Expr} = XML::XQL::buildNameSpaceExpr ($args{NameSpace}, 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1587
						$args{Name});
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1588
    bless \%args, $class;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1589
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1590
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1591
sub xql_check
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1592
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1593
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1594
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1595
sub xql_prepCache
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1596
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1597
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1598
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1599
sub solve
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1600
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1601
    my ($self, $context, $list) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1602
    my @result = ();
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1603
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1604
    my $expr = $self->{Expr};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1605
    for my $node (@$list)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1606
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1607
	for my $kid (@{$node->xql_element})
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1608
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1609
	    push @result, $kid if $kid->xql_nodeName =~ /$expr/;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1610
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1611
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1612
    \@result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1613
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1614
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1615
sub xql_contextString
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1616
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1617
    my $self = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1618
    my $name = $self->{Name};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1619
    my $space = $self->{NameSpace};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1620
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1621
    my $str = defined($space) ? "$space:$name" : $name;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1622
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1623
    XML::XQL::delim ($str, $self, @_);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1624
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1625
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1626
sub xql_toDOM
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1627
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1628
    my ($self, $doc) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1629
    my $elem = $self->SUPER::xql_toDOM ($doc);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1630
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1631
    my $name = $self->{Name};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1632
    my $space = $self->{NameSpace};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1633
    my $str = defined($space) ? "$space:$name" : $name;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1634
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1635
    $elem->setAttribute ("name", $str);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1636
    $elem;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1637
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1638
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1639
package XML::XQL::SimpleElement;	# "elem"
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1640
use base 'XML::XQL::Element';		# L -> L
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1641
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1642
sub solve
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1643
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1644
    my ($self, $context, $list) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1645
    my @result = ();
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1646
    my $name = $self->{Name};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1647
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1648
    for my $node (@$list)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1649
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1650
	push @result, @{ $node->xql_element ($name) };
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1651
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1652
    \@result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1653
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1654
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1655
package XML::XQL::AllElements;		# "*"
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1656
use base 'XML::XQL::Element';		# L -> L
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1657
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1658
sub solve
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1659
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1660
    my ($self, $context, $list) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1661
    my @result = ();
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1662
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1663
    for my $node (@$list)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1664
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1665
	push @result, @{$node->xql_element};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1666
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1667
    \@result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1668
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1669
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1670
package XML::XQL::Attribute;		# "@attr"
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1671
use base 'XML::XQL::Operator';		# L -> L of Attributes
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1672
use fields qw{ Name NameSpace Expr };
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1673
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1674
sub new
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1675
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1676
    my ($class, %args) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1677
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1678
    if (not defined ($args{NameSpace}))
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1679
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1680
	if ($args{Name} eq "*")
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1681
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1682
	    return bless \%args, 'XML::XQL::AllAttr';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1683
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1684
	else
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1685
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1686
	    return bless \%args, 'XML::XQL::SimpleAttr';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1687
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1688
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1689
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1690
    $args{Expr} = XML::XQL::buildNameSpaceExpr ($args{NameSpace}, 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1691
						$args{Name});
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1692
    bless \%args, $class;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1693
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1694
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1695
sub xql_check
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1696
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1697
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1698
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1699
sub xql_prepCache
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1700
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1701
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1702
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1703
sub solve
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1704
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1705
    my ($self, $context, $list) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1706
    my @result = ();
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1707
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1708
    my $expr = $self->{Expr};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1709
    for my $node (@$list)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1710
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1711
	for my $kid (@{$node->xql_attribute})
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1712
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1713
	    push @result, $kid if $kid->xql_nodeName =~ /$expr/;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1714
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1715
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1716
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1717
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1718
sub xql_contextString
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1719
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1720
    my $self = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1721
    my $name = $self->{Name};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1722
    my $space = $self->{NameSpace};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1723
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1724
    my $str = defined($space) ? "\@$space:$name" : ('@' . $name);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1725
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1726
    XML::XQL::delim ($str, $self, @_);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1727
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1728
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1729
package XML::XQL::SimpleAttr;		# "@attr"
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1730
use base 'XML::XQL::Attribute';		# L -> L
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1731
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1732
sub solve
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1733
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1734
    my ($self, $context, $list) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1735
    my @result = ();
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1736
    my $name = $self->{Name};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1737
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1738
    for my $node (@$list)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1739
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1740
	push @result, @{ $node->xql_attribute ($name) };
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1741
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1742
    \@result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1743
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1744
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1745
package XML::XQL::AllAttr;		# "@*"
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1746
use base 'XML::XQL::Attribute';		# L -> L
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1747
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1748
sub solve
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1749
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1750
    my ($self, $context, $list) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1751
    my @result = ();
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1752
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1753
    for my $node (@$list)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1754
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1755
	push @result, @{$node->xql_attribute};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1756
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1757
    \@result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1758
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1759
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1760
package XML::XQL::Subscript;		# "[3, 5 $to$ 7, -1]"
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1761
use base 'XML::XQL::Operator';		# L -> L
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1762
use fields qw{ IndexList };
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1763
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1764
#?? optimize for simple subscripts
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1765
sub solve
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1766
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1767
    my ($self, $context, $inlist) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1768
    my @result = ();
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1769
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1770
    for my $node (@$inlist)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1771
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1772
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1773
	my $list = $self->{Left}->solve ($context, [$node]);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1774
	$self->verbose("Left", $list);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1775
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1776
	my $n = int (@$list);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1777
	next if ($n == 0);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1778
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1779
	# build ordered index list
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1780
	my @indexFlags = ();
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1781
	$#indexFlags = $n - 1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1782
	
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1783
	my $index = $self->{IndexList};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1784
	my $len = @$index;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1785
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1786
#?? this is done a lot - optimize....	
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1787
	my $i = 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1788
	while ($i < $len)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1789
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1790
	    my $start = $index->[$i++];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1791
	    $start += $n if ($start < 0);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1792
	    my $end = $index->[$i++];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1793
	    $end += $n if ($end < 0);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1794
	    
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1795
	    next unless $start <= $end && $end >=0 && $start < $n;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1796
	    $start = 0 if ($start < 0);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1797
	    $end = $n-1 if ($end >= $n);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1798
	    
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1799
	    for my $j ($start .. $end)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1800
	    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1801
		$indexFlags[$j] = 1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1802
	    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1803
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1804
	for $i (0 .. $n-1)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1805
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1806
	    push @result, $list->[$i] if $indexFlags[$i];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1807
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1808
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1809
    \@result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1810
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1811
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1812
sub xql_contextString
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1813
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1814
    my $self = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1815
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1816
    my $index = $self->{IndexList};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1817
    my $str = XML::XQL::bold("[");
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1818
    for (my $i = 0; $i < @$index; $i++)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1819
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1820
	$str .= ", " if $i > 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1821
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1822
	my $s = $index->[$i++];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1823
	my $e = $index->[$i];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1824
	$str = ($s == $e) ? $s : "$s \$to\$ $e";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1825
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1826
    $str .= XML::XQL::bold("]");
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1827
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1828
    XML::XQL::delim ($self->{Left}->xql_contextString (@_) . $str, $self, @_);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1829
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1830
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1831
sub xql_toDOM
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1832
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1833
    my ($self, $doc) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1834
    my $elem = $self->SUPER::xql_toDOM ($doc);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1835
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1836
    my $index = $self->{IndexList};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1837
    my $str = "";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1838
    for (my $i = 0; $i < @$index; $i++)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1839
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1840
	$str .= ", " if $i > 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1841
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1842
	my $s = $index->[$i++];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1843
	my $e = $index->[$i];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1844
	$str .= ($s == $e) ? $s : "$s \$to\$ $e";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1845
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1846
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1847
    my $ie = $doc->createElement ("index");
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1848
    $ie->setAttribute ("list", $str);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1849
    $elem->appendChild ($ie);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1850
    $elem;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1851
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1852
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1853
package XML::XQL::Union;		# "book $union$ magazine", also "|"
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1854
use base 'XML::XQL::Operator';		# L x L -> L
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1855
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1856
sub solve
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1857
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1858
    my ($self, $context, $list) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1859
    my $left = XML::XQL::toList ($self->{Left}->solve ($context, $list));
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1860
    my $right = XML::XQL::toList ($self->{Right}->solve ($context, $list));
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1861
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1862
    return $right if (@$left < 1);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1863
    return $left if (@$right < 1);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1864
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1865
    my @result = @$left;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1866
    for my $node (@$right)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1867
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1868
	push @result, $node unless XML::XQL::listContains ($left, $node);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1869
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1870
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1871
    my $parent = $self->{Parent};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1872
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1873
    # Don't sort if parent is a Union or //, because the parent will do the sort
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1874
    unless (defined $parent and $parent->mustSort)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1875
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1876
	XML::XQL::sortDocOrder (\@result)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1877
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1878
#    $self->verbose ("Union result", \@result);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1879
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1880
    \@result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1881
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1882
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1883
sub mustSort
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1884
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1885
    1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1886
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1887
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1888
sub xql_contextString
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1889
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1890
    my $self = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1891
    XML::XQL::delim ($self->{Left}->xql_contextString (@_) . 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1892
		     XML::XQL::bold (" \$union\$ ") . 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1893
		     $self->{Right}->xql_contextString (@_), $self, @_);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1894
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1895
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1896
package XML::XQL::Intersect;		# "book $intersect$ magazine"
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1897
use base 'XML::XQL::Operator';		# L x L -> L
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1898
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1899
sub solve
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1900
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1901
    my ($self, $context, $list) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1902
    my $left = XML::XQL::toList ($self->{Left}->solve ($context, $list));
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1903
    return [] if @$left < 1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1904
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1905
    my $right = XML::XQL::toList ($self->{Right}->solve ($context, $list));
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1906
    return [] if @$right < 1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1907
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1908
    # Assumption: $left and $right don't have duplicates themselves
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1909
    my @result = ();
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1910
    for my $node (@$left)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1911
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1912
#? reimplement with hash - faster!
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1913
	push @result, $node if XML::XQL::listContains ($right, $node);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1914
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1915
    \@result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1916
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1917
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1918
sub xql_contextString
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1919
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1920
    my $self = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1921
    XML::XQL::delim ($self->{Left}->xql_contextString (@_) . 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1922
		     XML::XQL::bold (" \$intersect\$ ") . 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1923
		     $self->{Right}->xql_contextString (@_), $self, @_);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1924
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1925
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1926
package XML::XQL::Filter;		# "elem[expr]"
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1927
use base 'XML::XQL::Operator';		# L -> L
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1928
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1929
sub solve
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1930
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1931
    my ($self, $context, $inlist) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1932
    my @result = ();
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1933
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1934
    for my $node (@$inlist)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1935
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1936
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1937
	my $list = $self->{Left}->solve ($context, [$node]);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1938
	next if @$list == 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1939
	
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1940
	my $subQuery = $self->{Right};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1941
	
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1942
	$context = [0, scalar (@$list)];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1943
	for my $node (@$list)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1944
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1945
#?? optimize? only need the first one to succeed
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1946
	    my $r = $subQuery->solve ($context, [ $node ]);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1947
	    push @result, $node if XML::XQL::toBoolean ($r);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1948
	    $context->[0]++;	# increase the index for the index() method
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1949
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1950
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1951
    \@result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1952
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1953
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1954
sub xql_check
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1955
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1956
    my ($self, $inSubQuery, $inParam) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1957
    $self->{Left}->xql_check ($inSubQuery, $inParam);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1958
    $self->{Right}->xql_check (1, $inParam);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1959
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1960
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1961
sub xql_contextString
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1962
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1963
    my $self = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1964
    XML::XQL::delim ($self->{Left}->xql_contextString (@_) . 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1965
		     XML::XQL::bold ("[") . 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1966
		     $self->{Right}->xql_contextString (@_) . 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1967
		     XML::XQL::bold ("]"), $self, @_);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1968
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1969
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1970
package XML::XQL::BooleanOp;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1971
use base 'XML::XQL::Operator';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1972
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1973
package XML::XQL::Or;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1974
use base 'XML::XQL::BooleanOp';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1975
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1976
sub solve
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1977
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1978
    my ($self, $context, $list) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1979
    my $left = $self->{Left}->solve ($context, $list);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1980
    return $XML::XQL::Boolean::TRUE if XML::XQL::toBoolean ($left);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1981
    return $self->{Right}->solve ($context, $list);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1982
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1983
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1984
sub xql_contextString
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1985
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1986
    my $self = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1987
    XML::XQL::delim ($self->{Left}->xql_contextString (@_) . 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1988
		     XML::XQL::bold (" \$or\$ ") . 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1989
	   $self->{Right}->xql_contextString (@_), $self, @_);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1990
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1991
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1992
package XML::XQL::And;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1993
use base 'XML::XQL::BooleanOp';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1994
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1995
sub solve
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1996
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1997
    my ($self, $context, $list) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1998
    my $left = $self->{Left}->solve ($context, $list);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  1999
    return $XML::XQL::Boolean::FALSE unless XML::XQL::toBoolean ($left);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2000
    return $self->{Right}->solve ($context, $list);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2001
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2002
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2003
sub xql_contextString
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2004
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2005
    my $self = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2006
    XML::XQL::delim ($self->{Left}->xql_contextString (@_) . 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2007
		     XML::XQL::bold (" \$and\$ ") . 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2008
		     $self->{Right}->xql_contextString (@_), $self, @_);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2009
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2010
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2011
package XML::XQL::Not;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2012
use base 'XML::XQL::BooleanOp';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2013
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2014
sub solve
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2015
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2016
    my ($self, $context, $list) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2017
    my $left = $self->{Left}->solve ($context, $list);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2018
    return XML::XQL::toBoolean ($left) ? $XML::XQL::Boolean::FALSE : $XML::XQL::Boolean::TRUE;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2019
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2020
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2021
sub xql_contextString
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2022
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2023
    my $self = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2024
    XML::XQL::delim (XML::XQL::bold ("\$not\$ ") . 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2025
		     $self->{Left}->xql_contextString (@_), $self, @_);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2026
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2027
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2028
package XML::XQL::Compare;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2029
use base 'XML::XQL::Operator';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2030
use fields qw{ Func All };
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2031
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2032
use Carp;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2033
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2034
sub solve
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2035
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2036
    my ($self, $context, $list) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2037
    
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2038
    my $type;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2039
    my $cmpFunc = $self->{Func};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2040
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2041
    my $left = $self->verbose ("left", XML::XQL::toList ($self->{Left}->solve ($context, $list)));
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2042
    return [] if @$left < 1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2043
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2044
    my $right;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2045
    eval {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2046
	$right = $self->verbose ("right", XML::XQL::prepareRvalue ($self->{Right}->solve ($context, $list)));
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2047
    };
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2048
    return [] if XML::XQL::exception ($@);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2049
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2050
    if ($self->{All})
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2051
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2052
	for my $node (@$left)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2053
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2054
	    eval {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2055
		# Stop if any of the comparisons fails
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2056
		return [] unless &$cmpFunc ($node, $right);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2057
	    };
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2058
	    return [] if XML::XQL::exception ($@);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2059
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2060
	return $left;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2061
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2062
    else	# $any$ 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2063
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2064
        my @result = ();
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2065
	for my $node (@$left)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2066
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2067
	    eval {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2068
		push (@result, $node)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2069
		    if &$cmpFunc ($node, $right);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2070
	    };
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2071
	    return [] if XML::XQL::exception ($@);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2072
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2073
	return \@result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2074
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2075
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2076
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2077
sub xql_contextString
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2078
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2079
    my $self = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2080
    my $all = $self->{All} ? "\$all\$ " : "";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2081
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2082
    XML::XQL::delim ($all . $self->{Left}->xql_contextString (@_) . " " . 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2083
		     XML::XQL::bold ($self->{Oper}) . " " .
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2084
		     $self->{Right}->xql_contextString (@_), $self, @_);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2085
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2086
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2087
package XML::XQL::Func;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2088
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2089
use Carp;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2090
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2091
sub count
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2092
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2093
    my ($context, $list, $expr) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2094
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2095
    my $cnt;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2096
    if (defined $expr)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2097
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2098
	$list = XML::XQL::toList ($expr->solve ($context, $list));
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2099
	$cnt = @$list;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2100
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2101
    else
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2102
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2103
	$cnt = $context->[1];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2104
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2105
#?? ref node?
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2106
    new XML::XQL::Number ($cnt);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2107
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2108
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2109
sub id
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2110
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2111
    my ($context, $list, $query) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2112
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2113
    return [] if @$list == 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2114
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2115
    my $id = XML::XQL::prepareRvalue ($query->solve ($context, $list));
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2116
#?? check result?
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2117
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2118
#?? if [0] is not a Node, I should probably try the next one
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2119
    my $doc = $list->[0]->xql_document;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2120
    
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2121
    _findId ($doc->xql_element->[0], $id);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2122
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2123
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2124
sub _findId # static method
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2125
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2126
    my ($elem, $id) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2127
    my $attr = $elem->xql_attribute ("id");
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2128
    return [$elem] if (@$attr == 1 && $attr->[0]->xql_nodeName eq $id);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2129
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2130
    for my $kid (@{$elem->xql_element})
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2131
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2132
	$attr = _findId ($kid);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2133
	return $attr if @$attr;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2134
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2135
    return [];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2136
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2137
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2138
sub end
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2139
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2140
    my ($context, $list) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2141
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2142
    return [] if @$list == 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2143
    new XML::XQL::Boolean ($context->[0] == $context->[1] - 1);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2144
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2145
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2146
sub xql_index
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2147
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2148
    my ($context, $list) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2149
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2150
#    print "index: " . XML::XQL::d($context) . "\n";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2151
#?? wrong!
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2152
    return [] if @$list == 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2153
    new XML::XQL::Number ($context->[0]);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2154
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2155
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2156
sub ancestor
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2157
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2158
    my ($context, $list, $query) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2159
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2160
    return [] if @$list == 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2161
 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2162
    my @anc = ();
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2163
#?? fix for @$list > 1
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2164
    my $parent = $list->[0]->xql_parent;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2165
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2166
    while (defined $parent)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2167
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2168
	# keep list of ancestors so far
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2169
	unshift @anc, $parent;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2170
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2171
	# solve the query for the ancestor
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2172
	my $result = $query->solve ($context, [$parent]);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2173
	for my $node (@{$result})
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2174
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2175
	    for my $anc (@anc)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2176
	    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2177
		return [$node] if $node == $anc;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2178
	    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2179
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2180
	$parent = $parent->xql_parent;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2181
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2182
    return [];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2183
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2184
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2185
sub node
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2186
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2187
    my ($context, $list) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2188
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2189
    return [] if @$list == 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2190
    return $list->[0]->xql_node if @$list == 1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2191
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2192
    my @result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2193
    for my $node (@$list)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2194
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2195
	push @result, @{ $node->xql_node };
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2196
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2197
    XML::XQL::sortDocOrder (\@result);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2198
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2199
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2200
sub _nodesByType
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2201
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2202
    my ($list, $type) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2203
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2204
    return [] if @$list == 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2205
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2206
    my @result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2207
    for my $node (@$list)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2208
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2209
	for my $kid (@{ $node->xql_node })
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2210
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2211
	    push @result, $kid if $kid->xql_nodeType == $type;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2212
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2213
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2214
    @$list > 1 ? XML::XQL::sortDocOrder (\@result) : \@result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2215
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2216
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2217
sub pi
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2218
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2219
    my ($context, $list, $pi_name) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2220
    if (defined $pi_name)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2221
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2222
	return [] if @$list == 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2223
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2224
	$pi_name = $pi_name->solve ($context, $list)->xql_toString;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2225
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2226
	my @result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2227
	for my $node (@$list)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2228
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2229
	    for my $kid (@{ $node->xql_node })
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2230
	    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2231
		push @result, $kid 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2232
		    if $kid->xql_nodeType == 7 && $kid->getTarget eq $pi_name;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2233
	    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2234
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2235
	return @$list > 1 ? XML::XQL::sortDocOrder (\@result) : \@result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2236
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2237
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2238
    return _nodesByType ($_[1], 7);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2239
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2240
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2241
sub comment
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2242
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2243
    _nodesByType ($_[1], 8);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2244
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2245
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2246
sub textNode
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2247
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2248
    _nodesByType ($_[1], 3);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2249
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2250
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2251
sub nodeName
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2252
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2253
    my ($context, $list) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2254
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2255
    return [] if @$list == 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2256
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2257
    my @result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2258
    for my $node (@$list)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2259
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2260
	push @result, new XML::XQL::Text ($node->xql_nodeName, $node);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2261
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2262
    \@result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2263
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2264
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2265
sub namespace
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2266
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2267
    my ($context, $list) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2268
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2269
    return [] if @$list == 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2270
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2271
    my @result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2272
    for my $node (@$list)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2273
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2274
	my $namespace = $node->xql_namespace;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2275
	next unless defined $namespace;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2276
	push @result, new XML::XQL::Text ($namespace, $node);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2277
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2278
    \@result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2279
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2280
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2281
sub prefix
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2282
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2283
    my ($context, $list) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2284
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2285
    return [] if @$list == 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2286
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2287
    my @result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2288
    for my $node (@$list)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2289
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2290
	my $prefix = $node->xql_prefix;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2291
	next unless defined $prefix;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2292
	push @result, new XML::XQL::Text ($prefix, $node);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2293
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2294
    \@result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2295
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2296
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2297
sub baseName
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2298
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2299
    my ($context, $list) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2300
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2301
    return [] if @$list == 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2302
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2303
    my @result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2304
    for my $node (@$list)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2305
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2306
	my $basename = $node->xql_baseName;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2307
	next unless defined $basename;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2308
	push @result, new XML::XQL::Text ($basename, $node);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2309
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2310
    \@result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2311
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2312
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2313
sub nodeType
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2314
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2315
    my ($context, $list) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2316
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2317
    return [] if @$list == 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2318
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2319
    my @result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2320
    for my $node (@$list)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2321
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2322
	push @result, new XML::XQL::Number ($node->xql_nodeType, $node);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2323
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2324
    \@result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2325
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2326
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2327
sub nodeTypeString
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2328
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2329
    my ($context, $list) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2330
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2331
    return [] if @$list == 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2332
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2333
    my @result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2334
    for my $node (@$list)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2335
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2336
	push @result, new XML::XQL::Text ($node->xql_nodeTypeString, $node);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2337
    } 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2338
    @result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2339
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2340
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2341
sub value
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2342
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2343
    my ($context, $list) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2344
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2345
    return [] if @$list == 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2346
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2347
    my @result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2348
    for my $node (@$list)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2349
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2350
	push @result, $node->xql_value;	# value always returns an object
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2351
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2352
    \@result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2353
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2354
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2355
sub text
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2356
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2357
    my ($context, $list, $recurse) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2358
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2359
    return [] if @$list == 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2360
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2361
    if (defined $recurse)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2362
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2363
	$recurse = $recurse->solve ($context, $list)->xql_toString;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2364
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2365
    else
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2366
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2367
	$recurse = 1;		# default
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2368
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2369
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2370
    my @result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2371
    for my $node (@$list)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2372
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2373
	my $text = $node->xql_text ($recurse);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2374
	next unless defined $text;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2375
	
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2376
	push @result, new XML::XQL::Text ($text, $node);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2377
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2378
    \@result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2379
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2380
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2381
sub rawText
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2382
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2383
    my ($context, $list, $recurse) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2384
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2385
    return [] if @$list == 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2386
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2387
    if (defined $recurse)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2388
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2389
	$recurse = $recurse->solve ($context, $list)->xql_toString;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2390
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2391
    else
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2392
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2393
	$recurse = 1;		# default
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2394
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2395
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2396
    my @result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2397
    for my $node (@$list)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2398
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2399
	my $text = $node->xql_rawText ($recurse);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2400
	next unless defined $text;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2401
	
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2402
	push @result, new XML::XQL::Text ($text, $node);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2403
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2404
    \@result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2405
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2406
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2407
sub true
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2408
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2409
    return $XML::XQL::Boolean::TRUE;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2410
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2411
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2412
sub false
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2413
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2414
    return $XML::XQL::Boolean::FALSE;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2415
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2416
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2417
#sub date() is in XQL::XML::Date
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2418
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2419
sub element
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2420
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2421
    my ($context, $list, $text) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2422
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2423
    return [] if @$list == 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2424
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2425
    my @result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2426
    if (defined $text)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2427
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2428
	$text = XML::XQL::prepareRvalue ($text->solve ($context, $list))->xql_toString;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2429
	for my $node (@$list)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2430
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2431
	    push @result, @{$node->xql_element ($text)};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2432
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2433
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2434
    else
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2435
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2436
	for my $node (@$list)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2437
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2438
	    push @result, @{$node->xql_element};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2439
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2440
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2441
    @$list > 1 ? XML::XQL::sortDocOrder (\@result) : \@result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2442
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2443
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2444
sub attribute
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2445
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2446
    my ($context, $list, $text) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2447
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2448
    return [] if @$list == 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2449
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2450
    my @result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2451
    if (defined $text)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2452
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2453
	$text = XML::XQL::prepareRvalue ($text->solve ($context, $list))->xql_toString;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2454
	for my $node (@$list)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2455
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2456
	    push @result, @{ $node->xql_attribute ($text) };
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2457
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2458
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2459
    else
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2460
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2461
	for my $node (@$list)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2462
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2463
	    push @result, @{ $node->xql_attribute };
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2464
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2465
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2466
    \@result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2467
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2468
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2469
package XML::XQL::Bang;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2470
use base 'XML::XQL::Operator';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2471
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2472
sub solve
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2473
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2474
    my ($self, $context, $list) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2475
    $list = $self->{Left}->solve ($context, $list);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2476
    $self->{Right}->solve ($context, $list);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2477
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2478
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2479
sub xql_contextString
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2480
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2481
    my $self = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2482
    XML::XQL::delim ($self->{Left}->xql_contextString (@_) . 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2483
		     XML::XQL::bold ("!") .
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2484
		     $self->{Right}->xql_contextString (@_), $self, @_);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2485
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2486
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2487
package XML::XQL::Invocation;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2488
use base 'XML::XQL::Operator';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2489
use fields qw{ Args Name Type Once ConstVal };
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2490
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2491
use Carp;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2492
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2493
sub new
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2494
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2495
    my ($class, %args) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2496
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2497
    my $self = bless \%args, $class;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2498
    for my $par (@{$self->{Args}})
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2499
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2500
	$par->setParent ($self);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2501
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2502
    $self;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2503
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2504
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2505
sub dispose
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2506
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2507
    my $self = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2508
    for (@{ $self->{Args} })
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2509
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2510
	$_->dispose;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2511
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2512
    undef $self->{Args};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2513
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2514
    undef $self->{Parent};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2515
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2516
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2517
sub isConstant
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2518
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2519
    my ($self) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2520
    
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2521
    # An Invocation is constant, if all it's arguments are constant
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2522
    # and it's a "constant" function
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2523
    my $name = $self->{Name};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2524
    my $cf = $self->query->{ConstFunc};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2525
    my $const = exists ($cf->{$name}) ? 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2526
	$cf->{name} : $XML::XQL::ConstFunc{$name};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2527
    return 0 unless $const;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2528
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2529
    for my $par (@{$self->{Args}})
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2530
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2531
	return 0 unless $par->isConstant;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2532
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2533
    1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2534
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2535
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2536
sub xql_check
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2537
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2538
    my ($self, $inSubQuery, $inParam) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2539
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2540
    # Syntactic Constraint 7:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2541
    # In a node query this function or method is only valid inside an instance 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2542
    # of Subquery, unless it appears within an instance of Param.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2543
    # Functions and methods are valid anywhere in a full query.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2544
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2545
    my $query;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2546
    if (not ($inSubQuery or $inParam) and ($query = $self->query)->isNodeQuery)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2547
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2548
	unless ($query->isAllowedOutsideSubquery ($self->{Name}))
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2549
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2550
	  XML::XQL::parseError $self->{Type} . " " . $self->{Name} . 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2551
	    " is only allowed inside a Subquery or Param for 'Node Queries'." . 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2552
	    " Context: " . $self->toContextString;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2553
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2554
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2555
    for my $par (@{$self->{Args}})
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2556
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2557
	$par->xql_check ($inSubQuery, 1);	# these are Params
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2558
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2559
    # once() should only be evaluated once per query
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2560
    # "constant" functions should only be evaluated once *ever*
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2561
    $self->{Once} = $self->isOnce || $self->isConstant;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2562
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2563
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2564
sub xql_prepCache
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2565
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2566
    my ($self) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2567
    # once() should only be evaluated once per query
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2568
    # "constant" functions should only be evaluated once *ever*
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2569
    delete $self->{ConstVal} if $self->isOnce;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2570
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2571
    for my $par (@{$self->{Args}})
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2572
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2573
	$par->xql_prepCache;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2574
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2575
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2576
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2577
sub isOnce
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2578
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2579
    $_[0]->{Name} eq "once";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2580
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2581
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2582
sub isMethod
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2583
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2584
    $_[0]->{Type} eq "method";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2585
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2586
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2587
sub solve
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2588
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2589
    my ($self, $context, $list) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2590
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2591
    # Use the cached value if it's a "constant" function
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2592
    return $self->{ConstVal} if (exists $self->{ConstVal});
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2593
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2594
    my $func = $self->{Func};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2595
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2596
    my $result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2597
    eval {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2598
	$result = &$func ($context, $list, @{$self->{Args}});
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2599
	$self->{ConstVal} = $result if $self->{Once};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2600
    };
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2601
    if ($@)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2602
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2603
#?? or croak
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2604
	$self->warning ("invocation of '" . $self->{Name} . "' failed:\n\t$@");
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2605
	$self->{ConstVal} = [] if $self->{Once};
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2606
	return [];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2607
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2608
    $result;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2609
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2610
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2611
sub xql_contextString
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2612
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2613
    my $self = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2614
    
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2615
    my $str = XML::XQL::bold ($self->{Name}) . "(";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2616
    for (my $i = 0; $i < @{$self->{Args}}; $i++)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2617
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2618
	$str .= ", " if $i > 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2619
	$str .= $self->{Args}->[$i]->xql_contextString (@_);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2620
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2621
    $str .= ")";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2622
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2623
    XML::XQL::delim ($str, $self, @_);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2624
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2625
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2626
# Base class shared by Node and PrimitiveType
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2627
package XML::XQL::PrimitiveTypeBase;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2628
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2629
sub dispose
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2630
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2631
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2632
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2633
sub xql_check
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2634
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2635
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2636
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2637
sub xql_prepCache
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2638
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2639
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2640
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2641
sub xql_prevSibling
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2642
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2643
    undef;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2644
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2645
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2646
# This method returns an integer that determines how values should be casted
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2647
# for comparisons. If the left value (LHS) has a higher xql_primType, the
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2648
# right value (RHS) is cast to the type of the LHS (otherwise, the LHS is casted
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2649
# to the type of the LHS)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2650
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2651
# Values for certain types:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2652
#	Node	0	(always cast a node to a Text string first)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2653
#	Text	1
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2654
#	Number  2
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2655
#	Boolean 3
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2656
#	Date	4	(other classes automatically use 4 by default)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2657
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2658
sub xql_primType
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2659
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2660
    4;	# default for all classes other then Node, Text, Number, Boolean
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2661
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2662
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2663
sub xql_toBoolean
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2664
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2665
    1;	# it is true if it exists
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2666
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2667
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2668
sub xql_namespace
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2669
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2670
    undef;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2671
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2672
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2673
sub xql_baseName
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2674
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2675
    undef;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2676
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2677
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2678
sub xql_prefix
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2679
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2680
    undef;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2681
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2682
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2683
sub xql_sortKey
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2684
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2685
    my $src = $_[0]->xql_sourceNode;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2686
    $src ? $src->xql_sortKey : $XML::XQL::LAST_SORT_KEY;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2687
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2688
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2689
sub xql_toDOM
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2690
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2691
    my ($self, $doc) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2692
    my $name = ref $self;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2693
    $name =~ s/.*:://;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2694
    my $elem = $doc->createElement ($name);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2695
    $elem->setAttribute ("value", $self->xql_toString);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2696
    $elem;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2697
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2698
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2699
package XML::XQL::PrimitiveType;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2700
use vars qw( @ISA );
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2701
@ISA = qw( XML::XQL::PrimitiveTypeBase );
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2702
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2703
sub new
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2704
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2705
    my ($class, $val, $srcNode) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2706
    bless [$val, $srcNode], $class;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2707
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2708
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2709
sub isConstant
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2710
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2711
    1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2712
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2713
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2714
sub setParent
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2715
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2716
    # not defined
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2717
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2718
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2719
sub solve
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2720
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2721
    $_[0];	# evaluates to itself
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2722
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2723
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2724
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2725
# Derived classes should not override this method.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2726
# Override xql_toString instead.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2727
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2728
sub xql_contextString
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2729
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2730
    my $self = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2731
    
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2732
    XML::XQL::delim ($self->xql_toString, $self, @_);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2733
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2734
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2735
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2736
# Return the value of the Object as a primitive Perl value, i.e. an integer,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2737
# a float, or a string.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2738
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2739
sub xql_toString
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2740
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2741
    $_[0]->[0];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2742
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2743
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2744
sub xql_sourceNode
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2745
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2746
    $_[0]->[1];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2747
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2748
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2749
sub xql_setSourceNode
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2750
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2751
    $_[0]->[1] = $_[1];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2752
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2753
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2754
sub xql_setValue
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2755
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2756
    # This could potentially change the value of a constant in the XQL 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2757
    # query expression.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2758
    $_[0]->[0] = $_[1];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2759
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2760
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2761
sub xql_nodeType
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2762
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2763
    0;	# it's not a Node
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2764
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2765
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2766
sub xql_compare
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2767
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2768
    # Temporarily switch off $WARNING flag, to disable messages a la:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2769
    #  Argument "1993-02-14" isn't numeric in ncmp
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2770
    local $^W = 0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2771
    $_[0]->[0] <=> $_[1]->xql_toString;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2772
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2773
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2774
sub xql_eq { my $self = shift; $self->xql_compare (@_) == 0; }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2775
sub xql_ne { my $self = shift; $self->xql_compare (@_) != 0; }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2776
sub xql_lt { my $self = shift; $self->xql_compare (@_) < 0; }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2777
sub xql_le { my $self = shift; $self->xql_compare (@_) <= 0; }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2778
sub xql_gt { my $self = shift; $self->xql_compare (@_) > 0; }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2779
sub xql_ge { my $self = shift; $self->xql_compare (@_) >= 0; }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2780
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2781
package XML::XQL::Boolean;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2782
use vars qw( @ISA @EXPORT $TRUE $FALSE );
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2783
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2784
use Carp;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2785
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2786
@ISA = qw( XML::XQL::PrimitiveType );
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2787
@EXPORT = qw( $TRUE $FALSE );
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2788
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2789
$TRUE = new XML::XQL::Boolean (1);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2790
$FALSE = new XML::XQL::Boolean (0);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2791
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2792
sub xql_primType
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2793
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2794
    3;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2795
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2796
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2797
sub xql_toBoolean
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2798
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2799
    $_[0]->[0];	# evaluate it to its value
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2800
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2801
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2802
sub xql_negate
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2803
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2804
#?? do we need to keep track of a source node here?
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2805
    $_[0]->[0] ? $FALSE : $TRUE;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2806
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2807
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2808
sub xql_compare
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2809
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2810
#?? how do we convert string to boolean value
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2811
    $_[0]->[0] <=> ($_[1]->xql_toString ? 1 : 0);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2812
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2813
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2814
sub xql_lt { badComparisonError (@_); }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2815
sub xql_gt { badComparisonError (@_); }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2816
sub xql_le { badComparisonError (@_); }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2817
sub xql_ge { badComparisonError (@_); }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2818
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2819
sub badComparisonError
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2820
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2821
    croak 'comparison operator (other than =, !=, $ieq$, $ine$) not defined for type Boolean';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2822
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2823
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2824
package XML::XQL::Number;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2825
use vars qw( @ISA );
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2826
@ISA = qw( XML::XQL::PrimitiveType );
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2827
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2828
#use overload 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2829
#    'fallback' => 1,		# use default operators, if not specified
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2830
#    '""' => \&debug;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2831
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2832
sub debug
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2833
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2834
    "Number[" . $_[0]->[0] . "]";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2835
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2836
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2837
sub xql_primType
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2838
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2839
    2;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2840
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2841
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2842
package XML::XQL::Text;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2843
use vars qw( @ISA );
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2844
@ISA = qw( XML::XQL::PrimitiveType );
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2845
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2846
#use overload 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2847
#    'fallback' => 1,		# use default operators, if not specified
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2848
#    '""' => \&debug;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2849
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2850
sub debug
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2851
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2852
    "Text[" . $_[0]->[0] . "]";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2853
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2854
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2855
sub xql_primType
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2856
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2857
    1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2858
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2859
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2860
sub xql_compare
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2861
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2862
    my ($self, $other, $ignoreCase) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2863
    if ($ignoreCase)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2864
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2865
	my $lhs = $self->[0];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2866
	my $rhs = $other->xql_toString;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2867
	"\U$lhs" cmp "\U$rhs";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2868
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2869
    else
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2870
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2871
	$self->[0] cmp $other->xql_toString;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2872
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2873
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2874
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2875
# Declare package XML::XQL::Node so that XML implementations can say
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2876
# that their nodes derive from it:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2877
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2878
# This worked for me when I added XQL support for XML::DOM:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2879
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2880
# BEGIN
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2881
# {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2882
#    push @XML::DOM::Node::ISA, 'XML::XQL::Node';
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2883
# }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2884
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2885
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2886
package XML::XQL::Node;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2887
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2888
use vars qw( @ISA );
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2889
@ISA = qw( XML::XQL::PrimitiveTypeBase );
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2890
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2891
use Carp;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2892
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2893
sub xql_primType
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2894
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2895
    0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2896
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2897
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2898
sub xql_toBoolean
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2899
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2900
    1;	# it is true if it exists
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2901
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2902
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2903
sub xql_attribute
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2904
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2905
    [];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2906
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2907
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2908
sub xql_sourceNode
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2909
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2910
    $_[0];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2911
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2912
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2913
# Default implementation - override this for speed
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2914
sub xql_element
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2915
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2916
    my ($node, $elem) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2917
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2918
    my @list = ();
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2919
    if (defined $elem)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2920
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2921
	for my $kid (@{$_[0]->xql_node})
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2922
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2923
	    # 1: element
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2924
	    push @list, $kid 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2925
		if $kid->xql_nodeType == 1 && $kid->xql_nodeName eq $elem;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2926
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2927
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2928
    else
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2929
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2930
	for my $kid (@{$_[0]->xql_node})
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2931
	{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2932
	    push @list, $kid if $kid->xql_nodeType == 1;	# 1: element
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2933
	}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2934
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2935
    \@list;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2936
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2937
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2938
sub xql_text
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2939
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2940
    undef;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2941
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2942
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2943
sub xql_rawText
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2944
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2945
    undef;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2946
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2947
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2948
sub xql_rawTextBlocks
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2949
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2950
    undef;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2951
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2952
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2953
sub xql_value
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2954
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2955
    new XML::XQL::Text ($_[0]->xql_text ($_[1]), $_[0]);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2956
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2957
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2958
# Convert xql_value to Perl string (or undef if xql_value is undefined)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2959
sub xql_toString
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2960
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2961
    my $val = $_[0]->xql_value;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2962
    return undef if XML::XQL::isEmptyList ($val);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2963
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2964
    $val->xql_toString;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2965
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2966
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2967
sub xql_setValue
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2968
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2969
    # Not implemented for most node types
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2970
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2971
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2972
sub xql_data
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2973
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2974
    "";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2975
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2976
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2977
sub xql_nodeType
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2978
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2979
    0;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2980
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2981
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2982
sub xql_nodeName
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2983
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2984
    [];
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2985
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2986
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2987
# Java code from "XML:: Namespaces in 20 lines" by James Clark:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2988
# see: http://www.oasis-open.org/cover/clarkNS-980804.html
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2989
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2990
# String expandName(String name, Element element, boolean isAttribute) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2991
#   // The index of the colon character in the name.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2992
#   int colonIndex = name.indexOf(':');
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2993
#   // The name of the attribute that declares the namespace prefix.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2994
#   String declAttName;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2995
#   if (colonIndex == -1) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2996
#     // Default namespace applies only to element type names.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2997
#     if (isAttribute)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2998
#       return name;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  2999
#     declAttName = "xmlns";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3000
#   }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3001
#   else {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3002
#     String prefix = name.substring(0, colonIndex);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3003
#     // "xml:" is special
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3004
#     if (prefix.equals("xml"))
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3005
#       return name;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3006
#     declAttName = "xmlns:" + prefix;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3007
#   }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3008
#   for (; element != null; element = element.getParent()) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3009
#     String ns = element.getAttributeValue(declAttName);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3010
#     if (ns != null) {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3011
#       // Handle special meaning of xmlns=""
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3012
#       if (ns.length() == 0 && colonIndex == -1)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3013
#         return name;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3014
#       return ns + '+' + name.substring(colonIndex + 1);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3015
#     }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3016
#   }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3017
#   return null;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3018
# }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3019
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3020
# From "Namespaces in XML"
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3021
# at http://www.w3.org/TR/1998/WD-xml-names-19980916
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3022
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3023
# The prefix xml is by definition bound to the namespace name
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3024
# urn:Connolly:input:required. The prefix xmlns is used only for 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3025
# namespace bindings and is not itself bound to any namespace name. 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3026
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3027
my $DEFAULT_NAMESPACE = undef;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3028
my $XML_NAMESPACE = "urn:Connolly:input:required";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3029
#?? default namespace
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3030
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3031
sub xql_namespace
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3032
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3033
    my ($self) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3034
    my $nodeType = $self->xql_nodeType;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3035
    my $element = $self;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3036
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3037
    if ($nodeType == 2)		# 2: Attr
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3038
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3039
	$element = $self->xql_parent;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3040
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3041
    elsif ($nodeType != 1)	# 1: Element
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3042
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3043
	return undef;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3044
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3045
    my $name = $self->xql_nodeName;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3046
    my $declAttName;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3047
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3048
    if ($name =~ /([^:]+):([^:]+)/)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3049
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3050
	my ($prefix, $basename) = ($1, $2);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3051
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3052
	# "xml:" is special
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3053
	return $XML_NAMESPACE if $prefix eq "xml";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3054
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3055
	$declAttName = "xmlns:$prefix";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3056
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3057
    else
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3058
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3059
	# Default namespace applies only to element type names.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3060
	return $DEFAULT_NAMESPACE if $nodeType == 2;	# 2: Attr
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3061
#?? default namespace?
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3062
	$declAttName = "xmlns";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3063
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3064
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3065
    do
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3066
    {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3067
	my $ns = $element->xql_attribute ($declAttName);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3068
	next unless defined $ns;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3069
	return $ns->xql_rawText;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3070
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3071
	$element = $element->xql_parent;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3072
    }
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3073
    while (defined ($element) and $element->xql_nodeType == 1);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3074
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3075
    # namespace not found
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3076
    undef;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3077
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3078
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3079
sub xql_basename
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3080
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3081
    my ($self) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3082
    my $nodeType = $self->xql_nodeType;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3083
    return undef unless $nodeType == 1 || $nodeType == 2;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3084
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3085
    my $name = $self->xql_nodeName;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3086
    $name =~ s/^[^:]://;	    # strip prefix
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3087
    $name;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3088
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3089
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3090
sub xql_prefix
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3091
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3092
    my ($self) = @_;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3093
    my $nodeType = $self->xql_nodeType;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3094
    return undef unless $nodeType == 1 || $nodeType == 2;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3095
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3096
    $self->xql_nodeName =~ /^([^:]+):/;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3097
    $1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3098
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3099
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3100
# Used by ancestor()
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3101
sub xql_parent
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3102
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3103
    undef;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3104
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3105
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3106
my @NodeTypeString =
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3107
(
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3108
 "", "element", "attribute", "text", "", "", "", "processing_instruction", 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3109
 "comment", "document"
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3110
);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3111
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3112
sub xql_nodeTypeString
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3113
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3114
    my $i = $_[0]->xql_nodeType;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3115
    return $NodeTypeString[$i] if ($i >= 1 && $i <= 3 || $i >= 7 && $i <= 9);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3116
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3117
#?? what should this return?
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3118
    "<unknown xql_nodeType $i>";
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3119
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3120
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3121
if (not $XML::XQL::Restricted)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3122
{
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3123
    require XML::XQL::Plus;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3124
}
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3125
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3126
# All nodes should implement:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3127
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3128
#?? this section must be updated!!
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3129
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3130
# - xql_document
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3131
# - xql_node: return an unblessed list reference with childNodes (not 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3132
#	attributes)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3133
# - xql_nodeType (default implementation for XML::XQL::Node returns 0):
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3134
#   Element:			1
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3135
#   Element Attribute:		2
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3136
#   Markup-Delimited Region of Text (Text and CDATASection): 3
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3137
#   Processing Instruction:	7
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3138
#   Comment:			8
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3139
#   Document (Entity):		9
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3140
# - xql_text
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3141
# - xql_value (default implementation is xql_text)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3142
# - xql_parent: return parent node or undef (Document, DocumentFragment)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3143
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3144
# Element should define/override the following:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3145
# - xql_nodeName: return the element name
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3146
# - xql_attribute("attributeName"): return an unblessed reference to a list
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3147
#	with the attribute, or [] if no such attribute
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3148
# - xql_attribute(): return an unblessed reference to a list with 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3149
#	all attribute nodes
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3150
# - xql_baseName, xql_prefix
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3151
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3152
# Attribute:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3153
# - xql_nodeName: return the attribute name
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3154
# - xql_baseName, xql_prefix
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3155
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3156
# EntityReference:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3157
# - xql_data: return expanded text value
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3158
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3159
# Text, CDATASection:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3160
# - xql_data: return expanded text value
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3161
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3162
# -xql_element could be overriden to speed up performance
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3163
#
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3164
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3165
1;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3166
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3167
__END__
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3168
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3169
=head1 NAME
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3170
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3171
XML::XQL - A perl module for querying XML tree structures with XQL
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3172
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3173
=head1 SYNOPSIS
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3174
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3175
 use XML::XQL;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3176
 use XML::XQL::DOM;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3177
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3178
 $parser = new XML::DOM::Parser;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3179
 $doc = $parser->parsefile ("file.xml");
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3180
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3181
 # Return all elements with tagName='title' under the root element 'book'
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3182
 $query = new XML::XQL::Query (Expr => "book/title");
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3183
 @result = $query->solve ($doc);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3184
 $query->dispose; # Avoid memory leaks - Remove circular references
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3185
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3186
 # Or (to save some typing)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3187
 @result = XML::XQL::solve ("book/title", $doc);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3188
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3189
 # Or (to save even more typing)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3190
 @result = $doc->xql ("book/title");
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3191
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3192
=head1 DESCRIPTION
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3193
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3194
The XML::XQL module implements the XQL (XML Query Language) proposal
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3195
submitted to the XSL Working Group in September 1998.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3196
The spec can be found at: L<http://www.w3.org/TandS/QL/QL98/pp/xql.html>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3197
Most of the contents related to the XQL syntax can also be found in the
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3198
L<XML::XQL::Tutorial> that comes with this distribution. 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3199
Note that XQL is not the same as XML-QL!
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3200
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3201
The current implementation only works with the L<XML::DOM> module, but once the
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3202
design is stable and the major bugs are flushed out, other extensions might
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3203
follow, e.g. for XML::Grove.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3204
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3205
XQL was designed to be extensible and this implementation tries to stick to that.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3206
Users can add their own functions, methods, comparison operators and data types.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3207
Plugging in a new XML tree structure (like XML::Grove) should be a piece of cake.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3208
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3209
To use the XQL module, either
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3210
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3211
  use XML::XQL;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3212
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3213
or
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3214
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3215
  use XML::XQL::Strict;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3216
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3217
The Strict module only provides the core XQL functionality as found in the
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3218
XQL spec. By default (i.e. by using XML::XQL) you get 'XQL+', which has
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3219
some additional features.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3220
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3221
See the section L<Additional Features in XQL+> for the differences.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3222
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3223
This module is still in development. See the To-do list in XQL.pm for what
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3224
still needs to be done. Any suggestions are welcome, the sooner these 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3225
implementation issues are resolved, the faster we can all use this module.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3226
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3227
If you find a bug, you would do me great favor by sending it to me in the
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3228
form of a test case. See the file t/xql_template.t that comes with this distribution.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3229
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3230
If you have written a cool comparison operator, function, method or XQL data 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3231
type that you would like to share, send it to enno@att.com and I will
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3232
add it to this module.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3233
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3234
=head1 XML::XQL global functions
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3235
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3236
=over 4
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3237
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3238
=item solve (QUERY_STRING, INPUT_LIST...)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3239
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3240
 @result = XML::XQL::solve ("doc//book", $doc);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3241
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3242
This is provided as a shortcut for:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3243
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3244
 $query = new XML::XQL::Query (Expr => "doc//book");
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3245
 @result = $query->solve ($doc);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3246
 $query->dispose;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3247
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3248
Note that with L<XML::XQL::DOM>, you can also write (see L<XML::DOM::Node>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3249
for details):
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3250
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3251
 @result = $doc->xql ("doc//book");
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3252
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3253
=item setDocParser (PARSER)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3254
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3255
Sets the XML::DOM::Parser that is used by the new XQL+ document() method.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3256
By default it uses an XML::DOM::Parser that was created without any arguments,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3257
i.e.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3258
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3259
  $PARSER = new XML::DOM::Parser;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3260
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3261
=item defineFunction (NAME, FUNCREF, ARGCOUNT [, ALLOWED_OUTSIDE [, CONST, [QUERY_ARG]]])
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3262
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3263
Defines the XQL function (at the global level, i.e. for all newly created 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3264
queries) with the specified NAME. The ARGCOUNT parameter can either be a single
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3265
number or a reference to a list with numbers. 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3266
A single number expands to [ARGCOUNT, ARGCOUNT]. The list contains pairs of 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3267
numbers, indicating the number of arguments that the function allows. The value
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3268
-1 means infinity. E.g. [2, 5, 7, 9, 12, -1] means that the function can have
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3269
2, 3, 4, 5, 7, 8, 9, 12 or more arguments.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3270
The number of arguments is checked when parsing the XQL query string.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3271
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3272
The second parameter must be a reference to a Perl function or an anonymous
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3273
sub. E.g. '\&my_func' or 'sub { ... code ... }'
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3274
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3275
If ALLOWED_OUTSIDE (default is 0) is set to 1, the function or method may 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3276
also be used outside subqueries in I<node queries>.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3277
(See NodeQuery parameter in Query constructor)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3278
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3279
If CONST (default is 0) is set to 1, the function is considered to be 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3280
"constant". See L<Constant Function Invocations> for details.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3281
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3282
If QUERY_ARG (default is 0) is not -1, the argument with that index is
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3283
considered to be a 'query parameter'. If the query parameter is a subquery, 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3284
that returns multiple values, the result list of the function invocation will
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3285
contain one result value for each value of the subquery. 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3286
E.g. 'length(book/author)' will return a list of Numbers, denoting the string 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3287
lengths of all the author elements returned by 'book/author'.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3288
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3289
Note that only methods (not functions) may appear after a Bang "!" operator.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3290
This is checked when parsing the XQL query string.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3291
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3292
See also: defineMethod
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3293
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3294
=item generateFunction (NAME, FUNCNAME, RETURN_TYPE [, ARGCOUNT [, ALLOWED_OUTSIDE [, CONST [, QUERY_ARG]]]])
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3295
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3296
Generates and defines an XQL function wrapper for the Perl function with the
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3297
name FUNCNAME. The function name will be NAME in XQL query expressions.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3298
The return type should be one of the builtin XQL Data Types or a class derived
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3299
from XML::XQL::PrimitiveType (see L<Adding Data Types>.)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3300
See defineFunction for the meaning of ARGCOUNT, ALLOWED_OUTSIDE, CONST and
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3301
QUERY_ARG.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3302
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3303
Function values are always converted to Perl strings with xql_toString before
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3304
they are passed to the Perl function implementation. The function return value
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3305
is cast to an object of type RETURN_TYPE, or to the empty list [] if the
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3306
result is undef. It uses expandType to expand XQL primitive type names.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3307
If RETURN_TYPE is "*", it returns the function 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3308
result as is, unless the function result is undef, in which case it returns [].
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3309
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3310
=item defineMethod (NAME, FUNCREF, ARGCOUNT [, ALLOWED_OUTSIDE])
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3311
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3312
Defines the XQL method (at the global level, i.e. for all newly created 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3313
queries) with the specified NAME. The ARGCOUNT parameter can either be a single
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3314
number or a reference to a list with numbers. 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3315
A single number expands to [ARGCOUNT, ARGCOUNT]. The list contains pairs of 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3316
numbers, indicating the number of arguments that the method allows. The value
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3317
-1 means infinity. E.g. [2, 5, 7, 9, 12, -1] means that the method can have
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3318
2, 3, 4, 5, 7, 8, 9, 12 or more arguments.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3319
The number of arguments is checked when parsing the XQL query string.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3320
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3321
The second parameter must be a reference to a Perl function or an anonymous
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3322
sub. E.g. '\&my_func' or 'sub { ... code ... }'
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3323
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3324
If ALLOWED_OUTSIDE (default is 0) is set to 1, the function or method may 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3325
also be used outside subqueries in I<node queries>.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3326
(See NodeQuery parameter in Query constructor)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3327
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3328
Note that only methods (not functions) may appear after a Bang "!" operator.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3329
This is checked when parsing the XQL query string.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3330
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3331
See also: defineFunction
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3332
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3333
=item defineComparisonOperators (NAME => FUNCREF [, NAME => FUNCREF]*)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3334
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3335
Defines XQL comparison operators at the global level.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3336
The FUNCREF parameters must be a references to a Perl function or an anonymous
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3337
sub. E.g. '\&my_func' or 'sub { ... code ... }'
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3338
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3339
E.g. define the operators $my_op$ and $my_op2$:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3340
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3341
 defineComparisonOperators ('my_op' => \&my_op,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3342
                            'my_op2' => sub { ... insert code here ... });
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3343
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3344
=item defineElementValueConvertor (TAG_NAME, FUNCREF)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3345
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3346
Defines that the result of the value() call for Elements with the specified
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3347
TAG_NAME uses the specified function. The function will receive
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3348
two parameters. The second one is the TAG_NAME of the Element node 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3349
and the first parameter is the Element node itself.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3350
FUNCREF should be a reference to a Perl function, e.g. \&my_sub, or
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3351
an anonymous sub.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3352
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3353
E.g. to define that all Elements with tag name 'date-of-birth' should return
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3354
XML::XQL::Date objects:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3355
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3356
	defineElementValueConvertor ('date-of-birth', sub {
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3357
		my $elem = shift;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3358
		# Always pass in the node as the second parameter. This is
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3359
		# the reference node for the object, which is used when
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3360
		# sorting values in document order.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3361
		new XML::XQL::Date ($elem->xql_text, $elem); 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3362
	});
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3363
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3364
These convertors can only be specified at a global level, not on a per query
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3365
basis. To undefine a convertor, simply pass a FUNCREF of undef.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3366
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3367
=item defineAttrValueConvertor (ELEM_TAG_NAME, ATTR_NAME, FUNCREF)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3368
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3369
Defines that the result of the value() call for Attributes with the specified
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3370
ATTR_NAME and a parent Element with the specified ELEM_TAG_NAME 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3371
uses the specified function. An ELEM_TAG_NAME of "*" will match regardless of
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3372
the tag name of the parent Element. The function will receive
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3373
3 parameters. The third one is the tag name of the parent Element (even if 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3374
ELEM_TAG_NAME was "*"), the second is the ATTR_NAME and the first is the 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3375
Attribute node itself.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3376
FUNCREF should be a reference to a Perl function, e.g. \&my_sub, or
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3377
an anonymous sub.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3378
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3379
These convertors can only be specified at a global level, not on a per query
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3380
basis. To undefine a convertor, simply pass a FUNCREF of undef.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3381
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3382
=item defineTokenQ (Q)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3383
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3384
Defines the token for the q// string delimiters at a global level.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3385
The default value for XQL+ is 'q', for XML::XQL::Strict it is undef.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3386
A value of undef will deactivate this feature.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3387
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3388
=item defineTokenQQ (QQ)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3389
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3390
Defines the token for the qq// string delimiters at a global level.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3391
The default value for XQL+ is 'qq', for XML::XQL::Strict it is undef.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3392
A value of undef will deactivate this feature.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3393
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3394
=item expandType (TYPE)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3395
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3396
Used internally to expand type names of XQL primitive types.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3397
E.g. it expands "Number" to "XML::XQL::Number" and is not case-sensitive, so
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3398
"number" and "NuMbEr" will both expand correctly.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3399
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3400
=item defineExpandedTypes (ALIAS, FULL_NAME [, ...])
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3401
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3402
For each pair of arguments it allows the class name FULL_NAME to be abbreviated
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3403
with ALIAS. The definitions are used by expandType(). 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3404
(ALIAS is always converted to lowercase internally, because expandType 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3405
is case-insensitive.)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3406
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3407
Overriding the ALIAS for "date", also affects the object type returned by the
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3408
date() function.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3409
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3410
=item setErrorContextDelimiters (START, END, BOLD_ON, BOLD_OFF)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3411
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3412
Sets the delimiters used when printing error messages during query evaluation.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3413
The default delimiters on Unix are `tput smul` (underline on) and `tput rmal`
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3414
(underline off). On other systems (that don't have tput), the delimiters are
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3415
">>" and "<<" resp. 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3416
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3417
When printing the error message, the subexpression that caused the error will
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3418
be enclosed by the delimiters, i.e. underlined on Unix.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3419
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3420
For certain subexpressions the significant keyword, e.g. "$and$" is enclosed in 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3421
the bold delimiters BOLD_ON (default: `tput bold` on Unix, "" elsewhere) and 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3422
BOLD_OFF (default: (`tput rmul` . `tput smul`) on Unix, "" elsewhere, 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3423
see $BoldOff in XML::XQL::XQL.pm for details.)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3424
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3425
=item isEmptyList (VAR)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3426
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3427
Returns 1 if VAR is [], else 0. Can be used in user defined functions.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3428
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3429
=back
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3430
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3431
=head1 Additional Features in XQL+
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3432
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3433
=over 4
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3434
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3435
=item Parent operator '..'
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3436
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3437
The '..' operator returns the parent of the current node, where '.' would
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3438
return the current node. This is not part of any XQL standard, because you
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3439
would normally use return operators, which are not implemented here.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3440
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3441
=item Sequence operators ';' and ';;'
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3442
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3443
The sequence operators ';' (precedes) and ';;' (immediately precedes) are
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3444
not in the XQL spec, but are described in 'The Design of XQL' by Jonathan Robie
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3445
who is one of the designers of XQL. It can be found at
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3446
L<http://www.texcel.no/whitepapers/xql-design.html>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3447
See also the XQL Tutorial for a description of what they mean.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3448
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3449
=item q// and qq// String Tokens
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3450
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3451
String tokens a la q// and qq// are allowed. q// evaluates like Perl's single 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3452
quotes and qq// like Perl's double quotes. Note that the default XQL strings do
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3453
not allow escaping etc., so it's not possible to define a string with both
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3454
single and double quotes. If 'q' and 'qq' are not to your liking, you may
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3455
redefine them to something else or undefine them altogether, by assigning undef
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3456
to them. E.g:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3457
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3458
 # at a global level - shared by all queries (that don't (re)define 'q')
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3459
 XML::XQL::defineTokenQ ('k');
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3460
 XML::XQL::defineTokenQQ (undef);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3461
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3462
 # at a query level - only defined for this query
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3463
 $query = new XML::XQL::Query (Expr => "book/title", q => 'k', qq => undef);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3464
 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3465
From now on k// works like q// did and qq// doesn't work at all anymore.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3466
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3467
=item Query strings can have embedded Comments
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3468
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3469
For example:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3470
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3471
 $queryExpr = "book/title          # this comment is inside the query string
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3472
	       [. = 'Moby Dick']"; # this comment is outside 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3473
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3474
=item Optional dollar delimiters and case-insensitive XQL keywords
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3475
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3476
The following XQL keywords are case-insensitive and the dollar sign delimiters 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3477
may be omitted: $and$, $or$, $not$, $union$, $intersect$, $to$, $any$, $all$,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3478
$eq$, $ne$, $lt$, $gt$, $ge$, $le$, $ieq$, $ine$, $ilt$, $igt$, $ige$, $ile$.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3479
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3480
E.g. $AND$, $And$, $aNd$, and, And, aNd are all valid replacements for $and$.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3481
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3482
Note that XQL+ comparison operators ($match$, $no_match$, $isa$, $can$) still
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3483
require dollar delimiters and are case-sensitive.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3484
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3485
=item Comparison operator: $match$ or '=~'
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3486
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3487
E.g. "book/title =~ '/(Moby|Dick)/']" will return all book titles containing
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3488
Moby or Dick. Note that the match expression needs to be quoted and should
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3489
contain the // or m// delimiters for Perl.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3490
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3491
When casting the values to be matched, both are converted to Text.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3492
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3493
=item Comparison operator: $no_match$ or '!~'
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3494
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3495
E.g. "book/title !~ '/(Moby|Dick)/']" will return all book titles that don't 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3496
contain Moby or Dick. Note that the match expression needs to be quoted and 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3497
should contain the // or m// delimiters for Perl.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3498
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3499
When casting the values to be matched, both are converted to Text.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3500
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3501
=item Comparison operator: $isa$
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3502
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3503
E.g. '//. $isa$ "XML::XQL::Date"' returns all elements for which the value() 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3504
function returns an XML::XQL::Date object. (Note that the value() function can
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3505
be overridden to return a specific object type for certain elements and 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3506
attributes.) It uses expandType to expand XQL primitive type names.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3507
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3508
=item Comparison operator: $can$
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3509
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3510
E.g. '//. $can$ "swim"' returns all elements for which the value() 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3511
function returns an object that implements the (Perl) swim() method. 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3512
(Note that the value() function can be overridden to return a specific object 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3513
type for certain elements and attributes.)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3514
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3515
=item Function: once (QUERY)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3516
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3517
E.g. 'once(id("foo"))' will evaluate the QUERY expression only once per query.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3518
Certain query results (like the above example) will always return the same
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3519
value within a query. Using once() will cache the QUERY result for the
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3520
rest of the query. 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3521
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3522
Note that "constant" function invocations are always cached.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3523
See also L<Constant Function Invocations>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3524
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3525
=item Function: subst (QUERY, EXPR, EXPR [,MODIFIERS, [MODE]])
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3526
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3527
E.g. 'subst(book/title, "[M|m]oby", "Dick", "g")' will replace Moby or moby
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3528
with Dick globally ("g") in all book title elements. Underneath it uses Perl's
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3529
substitute operator s///. Don't worry about which delimiters are used underneath.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3530
The function returns all the book/titles for which a substitution occurred.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3531
The default MODIFIERS string is "" (empty.) The function name may be abbreviated 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3532
to "s".
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3533
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3534
For most Node types, it converts the value() to a string (with xql_toString)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3535
to match the string and xql_setValue to set the new value in case it matched.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3536
For XQL primitives (Boolean, Number, Text) and other data types (e.g. Date) it 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3537
uses xql_toString to match the String and xql_setValue to set the result. 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3538
Beware that performing a substitution on a primitive that was found in the 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3539
original XQL query expression, changes the value of that constant.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3540
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3541
If MODE is 0 (default), it treats Element nodes differently by matching and
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3542
replacing I<text blocks> occurring in the Element node. A text block is defined
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3543
as the concatenation of the raw text of subsequent Text, CDATASection and 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3544
EntityReference nodes. In this mode it skips embedded Element nodes.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3545
If a text block matches, it is replaced by a single Text node, regardless
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3546
of the original node type(s).
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3547
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3548
If MODE is 1, it treats Element nodes like the other nodes, i.e. it converts
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3549
the value() to a string etc. Note that the default implementation of value()
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3550
calls text(), which normalizes whitespace and includes embedded Element
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3551
descendants (recursively.) This is probably not what you want to use in most
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3552
cases, but since I'm not a professional psychic... :-)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3553
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3554
=item Function: map (QUERY, CODE)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3555
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3556
E.g. 'map(book/title, "s/[M|m]oby/Dick/g; $_")' will replace Moby or moby
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3557
with Dick globally ("g") in all book title elements. Underneath it uses Perl's
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3558
map operator. The function returns all the book/titles for which a 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3559
change occurred.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3560
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3561
??? add more specifics
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3562
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3563
=item Function: eval (EXPR [,TYPE])
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3564
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3565
Evaluates the Perl expression EXPR and returns an object of the specified TYPE.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3566
It uses expandType to expand XQL primitive type names.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3567
If the result of the eval was undef, the empty list [] is returned.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3568
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3569
E.g. 'eval("2 + 5", "Number")' returns a Number object with the value 7, and
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3570
     'eval("%ENV{USER}")' returns a Text object with the user name.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3571
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3572
Consider using once() to cache the return value, when the invocation will 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3573
return the same result for each invocation within a query.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3574
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3575
??? add more specifics
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3576
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3577
=item Function: new (TYPE [, QUERY [, PAR] *])
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3578
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3579
Creates a new object of the specified object TYPE. The constructor may have any
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3580
number of arguments. The first argument of the constructor (the 2nd argument 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3581
of the new() function) is considered to be a 'query parameter'.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3582
See defineFunction for a definition of I<query parameter>.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3583
It uses expandType to expand XQL primitive type names.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3584
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3585
=item Function: document (QUERY) or doc (QUERY)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3586
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3587
The document() function creates a new L<XML::XML::Document> for each result 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3588
of QUERY (QUERY may be a simple string expression, like "/usr/enno/file.xml". 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3589
See t/xql_document.t or below for an example with a more complex QUERY.)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3590
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3591
document() may be abbreviated to doc().
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3592
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3593
document() uses an XML::DOM::Parser underneath, which can be set with
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3594
XML::XQL::setDocParser(). By default it uses a parser that was created without
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3595
any arguments, i.e.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3596
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3597
  $PARSER = new XML::DOM::Parser;
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3598
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3599
Let's try a more complex example, assuming $doc contains:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3600
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3601
 <doc>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3602
  <file name="file1.xml"/>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3603
  <file name="file2.xml"/>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3604
 </doc>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3605
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3606
Then the following query will return two L<XML::XML::Document>s, 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3607
one for file1.xml and one for file2.xml:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3608
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3609
 @result = XML::XQL::solve ("document(doc/file/@name)", $doc);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3610
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3611
The resulting documents can be used as input for following queries, e.g.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3612
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3613
 @result = XML::XQL::solve ("document(doc/file/@name)/root/bla", $doc);
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3614
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3615
will return all /root/bla elements from the documents returned by document().
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3616
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3617
=item Method: DOM_nodeType ()
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3618
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3619
Returns the DOM node type. Note that these are mostly the same as nodeType(),
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3620
except for CDATASection and EntityReference nodes. DOM_nodeType() returns
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3621
4 and 5 respectively, whereas nodeType() returns 3, because they are 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3622
considered text nodes.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3623
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3624
=item Function wrappers for Perl builtin functions
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3625
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3626
XQL function wrappers have been provided for most Perl builtin functions.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3627
When using a Perl builtin function like "substr" in an XQL+ querry, an
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3628
XQL function wrapper will be generated on the fly. The arguments to these
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3629
functions may be regular XQL+ subqueries (that return one or more values) for
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3630
a I<query parameter> (see generateFunction for a definition.)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3631
Most wrappers of Perl builtin functions have argument 0 for a query parameter,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3632
except for: chmod (parameter 1 is the query parameter), chown (2) and utime (2).
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3633
The following functions have no query parameter, which means that all parameters
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3634
should be a single value: atan2, rand, srand, sprintf, rename, unlink, system.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3635
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3636
The function result is casted to the appropriate XQL primitive type (Number, 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3637
Text or Boolean), or to an empty list if the result was undef.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3638
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3639
=back
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3640
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3641
=head2 XPath functions and methods
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3642
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3643
The following functions were found in the XPath specification:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3644
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3645
=over 4
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3646
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3647
=item Function: concat (STRING, STRING, STRING*) 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3648
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3649
The concat function returns the concatenation of its arguments.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3650
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3651
=item Function: starts-with (STRING, STRING) 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3652
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3653
The starts-with function returns true if the first argument string starts with 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3654
the second argument string, and otherwise returns false.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3655
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3656
=item Function: contains (STRING, STRING) 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3657
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3658
The contains function returns true if the first argument string contains the 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3659
second argument string, and otherwise returns false.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3660
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3661
=item Function: substring-before (STRING, STRING) 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3662
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3663
The substring-before function returns the substring of the first argument 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3664
string that precedes the first occurrence of the second argument string
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3665
in the first argument string, or the empty string if the first argument 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3666
string does not contain the second argument string. For example,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3667
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3668
 substring-before("1999/04/01","/") returns 1999.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3669
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3670
=item Function: substring-after (STRING, STRING) 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3671
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3672
The substring-after function returns the substring of the first argument string 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3673
that follows the first occurrence of the second argument string in
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3674
the first argument string, or the empty string if the first argument string does
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3675
not contain the second argument string. For example,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3676
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3677
 substring-after("1999/04/01","/") returns 04/01, 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3678
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3679
and 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3680
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3681
 substring-after("1999/04/01","19") returns 99/04/01.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3682
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3683
=item Function: substring (STRING, NUMBER [, NUMBER] ) 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3684
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3685
The substring function returns the substring of the first argument starting at 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3686
the position specified in the second argument with length specified in
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3687
the third argument. For example, 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3688
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3689
 substring("12345",2,3) returns "234". 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3690
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3691
If the third argument is not specified, it returns the substring 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3692
starting at the position specified in the second argument and continuing to 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3693
the end of the string. For example, 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3694
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3695
 substring("12345",2) returns "2345".
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3696
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3697
More precisely, each character in the string is considered 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3698
to have a numeric position: the position of the first character is 1,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3699
the position of the second character is 2 and so on.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3700
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3701
NOTE: This differs from the B<substr> method , in which the
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3702
method treats the position of the first character as 0.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3703
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3704
The XPath spec says this about rounding, but that is not true in this 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3705
implementation: 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3706
I<The returned substring contains those characters for which the position of the 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3707
character is greater than or equal to the rounded value of the
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3708
second argument and, if the third argument is specified, less than the 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3709
sum of the rounded value of the second argument and the rounded value of
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3710
the third argument; the comparisons and addition used for the above 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3711
follow the standard IEEE 754 rules; rounding is done as if by a call to the
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3712
round function.>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3713
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3714
=item Method: string-length ( [ QUERY ] )
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3715
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3716
The string-length returns the number of characters in the string. 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3717
If the argument is omitted, it defaults to the context node
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3718
converted to a string, in other words the string-value of the context node.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3719
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3720
Note that the generated XQL wrapper for the Perl built-in B<substr> does not
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3721
allow the argument to be omitted.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3722
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3723
=item Method: normalize-space ( [ QUERY ] )
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3724
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3725
The normalize-space function returns the argument string with whitespace 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3726
normalized by stripping leading and trailing whitespace and replacing
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3727
sequences of whitespace characters by a single space. Whitespace characters are 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3728
the same as those allowed by the S production in XML. If the
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3729
argument is omitted, it defaults to the context node converted to a string, in 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3730
other words the string-value of the context node.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3731
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3732
=item Function: translate (STRING, STRING, STRING) 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3733
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3734
The translate function returns the first argument string with occurrences of 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3735
characters in the second argument string replaced by the character at
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3736
the corresponding position in the third argument string. For example, 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3737
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3738
 translate("bar","abc","ABC") returns the string BAr. 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3739
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3740
If there is a
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3741
character in the second argument string with no character at a corresponding
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3742
position in the third argument string (because the second argument
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3743
string is longer than the third argument string), then occurrences of that 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3744
character in the first argument string are removed. For example,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3745
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3746
 translate("--aaa--","abc-","ABC") returns "AAA". 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3747
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3748
If a character occurs more than once in the second argument string, then the 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3749
first occurrence determines the replacement character. If the third argument 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3750
string is longer than the second argument string, then excess characters
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3751
are ignored.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3752
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3753
NOTE: The translate function is not a sufficient solution for case conversion 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3754
in all languages. A future version may
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3755
provide additional functions for case conversion.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3756
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3757
This function was implemented using tr///d.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3758
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3759
=item Function: sum ( QUERY ) 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3760
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3761
The sum function returns the sum of the QUERY results, by
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3762
converting the string values of each result to a number.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3763
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3764
=item Function: floor (NUMBER) 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3765
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3766
The floor function returns the largest (closest to positive infinity) number 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3767
that is not greater than the argument and that is an integer.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3768
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3769
=item Function: ceiling (NUMBER) 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3770
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3771
The ceiling function returns the smallest (closest to negative infinity) number 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3772
that is not less than the argument and that is an integer.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3773
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3774
=item Function: round (NUMBER) 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3775
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3776
The round function returns the number that is closest to the argument 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3777
and that is an integer. If there are two such numbers, then the one that is
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3778
closest to positive infinity is returned.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3779
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3780
=back
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3781
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3782
=head1 Implementation Details
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3783
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3784
=over 4
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3785
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3786
=item XQL Builtin Data Types
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3787
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3788
The XQL engine uses the following object classes internally. Only Number, 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3789
Boolean and Text are considered I<primitive XQL types>:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3790
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3791
=over 4
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3792
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3793
=item * XML::XQL::Number
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3794
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3795
For integers and floating point numbers.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3796
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3797
=item * XML::XQL::Boolean
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3798
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3799
For booleans, e.g returned by true() and false().
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3800
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3801
=item * XML::XQL::Text
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3802
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3803
For string values.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3804
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3805
=item * XML::XQL::Date
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3806
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3807
For date, time and date/time values. E.g. returned by the date() function.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3808
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3809
=item * XML::XQL::Node
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3810
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3811
Superclass of all XML node types. E.g. all subclasses of XML::DOM::Node subclass
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3812
from this.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3813
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3814
=item * Perl list reference
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3815
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3816
Lists of values are passed by reference (i.e. using [] delimiters).
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3817
The empty list [] has a double meaning. It also means 'undef' in certain 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3818
situations, e.g. when a function invocation or comparison failed.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3819
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3820
=back
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3821
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3822
=item Type casting in comparisons
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3823
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3824
When two values are compared in an XML comparison (e.g. $eq$) the values are
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3825
first casted to the same data type. Node values are first replaced by their
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3826
value() (i.e. the XQL value() function is used, which returns a Text value by 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3827
default, but may return any data type if the user so chooses.)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3828
The resulting values are then casted to the type of the object with the highest
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3829
xql_primType() value. They are as follows: Node (0), Text (1), Number (2),
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3830
Boolean (3), Date (4), other data types (4 by default, but this may be
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3831
overriden by the user.)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3832
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3833
E.g. if one value is a Text value and the other is a Number, the Text value is 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3834
cast to a Number and the resulting low-level (Perl) comparison is (for $eq$):
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3835
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3836
 $number->xql_toString == $text->xql_toString
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3837
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3838
If both were Text values, it would have been
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3839
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3840
 $text1->xql_toString eq $text2->xql_toString
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3841
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3842
Note that the XQL spec is vague and even conflicting where it concerns type
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3843
casting. This implementation resulted after talking to Joe Lapp, one of the
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3844
spec writers.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3845
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3846
=item Adding Data Types
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3847
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3848
If you want to add your own data type, make sure it derives from 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3849
XML::XQL::PrimitiveType and implements the necessary methods.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3850
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3851
I will add more stuff here to explain it all, but for now, look at the code
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3852
for the primitive XQL types or the Date class (L<XML::XQL::Date> in Date.pm.)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3853
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3854
=item Document Order
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3855
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3856
The XQL spec states that query results always return their values in 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3857
I<document order>, which means the order in which they appeared in the original
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3858
XML document. Values extracted from Nodes (e.g. with value(), text(), rawText(),
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3859
nodeName(), etc.) always have a pointer to the reference node (i.e. the Node
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3860
from which the value was extracted.) These pointers are acknowledged when
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3861
(intermediate) result lists are sorted. Currently, the only place where a
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3862
result list is sorted is in a $union$ expression, which is the only place
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3863
where the result list can be unordered.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3864
(If you find that this is not true, let me know.)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3865
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3866
Non-node values that have no associated reference node, always end up at the end
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3867
of the result list in the order that they were added.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3868
The XQL spec states that the reference node for an XML Attribute is the Element
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3869
to which it belongs, and that the order of values with the same reference node
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3870
is undefined. This means that the order of an Element and its attributes would 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3871
be undefined.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3872
But since the XML::DOM module keeps track of the order of the attributes, the
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3873
XQL engine does the same, and therefore, the attributes of an Element are
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3874
sorted and appear after their parent Element in a sorted result list.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3875
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3876
=item Constant Function Invocations
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3877
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3878
If a function always returns the same value when given "constant" arguments,
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3879
the function is considered to be "constant". A "constant" argument can be
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3880
either an XQL primitive (Number, Boolean, Text) or a "constant" function
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3881
invocation. E.g. 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3882
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3883
 date("12-03-1998")
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3884
 true()
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3885
 sin(0.3)
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3886
 length("abc")
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3887
 date(substr("12-03-1998 is the date", 0, 10))
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3888
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3889
are constant, but not:
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3890
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3891
 length(book[2])
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3892
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3893
Results of constant function invocations are cached and calculated only once
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3894
for each query. See also the CONST parameter in defineFunction.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3895
It is not necessary to wrap constant function invocations in a once() call.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3896
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3897
Constant XQL functions are: date, true, false and a lot of the XQL+
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3898
wrappers for Perl builtin functions. Function wrappers for certain builtins
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3899
are not made constant on purpose to force the invocation to be evaluated
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3900
every time, e.g. 'mkdir("/user/enno/my_dir", "0644")' (although constant
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3901
in appearance) may return different results for multiple invocations. 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3902
See %PerlFunc in Plus.pm for details.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3903
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3904
=item Function: count ([QUERY])
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3905
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3906
The count() function has no parameters in the XQL spec. In this implementation
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3907
it will return the number of QUERY results when passed a QUERY parameter.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3908
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3909
=item Method: text ([RECURSE])
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3910
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3911
When expanding an Element node, the text() method adds the expanded text() value
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3912
of sub-Elements. When RECURSE is set to 0 (default is 1), it will not include
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3913
sub-elements. This is useful e.g. when using the $match$ operator in a recursive
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3914
context (using the // operator), so it won't return parent Elements when one of
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3915
the children matches.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3916
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3917
=item Method: rawText ([RECURSE])
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3918
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3919
See text().
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3920
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3921
=back
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3922
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3923
=head1 SEE ALSO
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3924
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3925
L<XML::XQL::Query>, L<XML::XQL::DOM>, L<XML::XQL::Date>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3926
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3927
The Japanese version of this document can be found on-line at
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3928
L<http://member.nifty.ne.jp/hippo2000/perltips/xml/xql.htm>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3929
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3930
The L<XML::XQL::Tutorial> manual page. The Japanese version can be found at 
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3931
L<http://member.nifty.ne.jp/hippo2000/perltips/xml/xql/tutorial.htm>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3932
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3933
The XQL spec at L<http://www.w3.org/TandS/QL/QL98/pp/xql.html>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3934
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3935
The Design of XQL at L<http://www.texcel.no/whitepapers/xql-design.html>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3936
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3937
The DOM Level 1 specification at L<http://www.w3.org/TR/REC-DOM-Level-1>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3938
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3939
The XML spec (Extensible Markup Language 1.0) at L<http://www.w3.org/TR/REC-xml>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3940
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3941
The L<XML::Parser> and L<XML::Parser::Expat> manual pages.
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3942
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3943
=head1 AUTHOR
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3944
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3945
Please send bugs, comments and suggestions to Enno Derksen <F<enno@att.com>>
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3946
3f65fd25dfd4 sync up SVN codes
kelvzhu
parents:
diff changeset
  3947
=cut