| Net-Z3950-PQF documentation | Contained in the Net-Z3950-PQF distribution. |
Net::Z3950::PQF::Node - Abstract class for nodes in a PQF parse tree
$node = new Net::Z3950::PQF::TermNode('unix');
$node->isa("Net::Z3950::PQF::Node") or die "oops";
This module implements the types for the nodes that make up a PQF
parse tree. Each such concrete type is a subclass of the abstract
base class
Net::Z3950::Node,
and has a type whose name is of the form
Net::Z3950::PQF::somethingNode.
The following node types are defined:
TermNodeRepresents an actual query term such as
brian,
"brian"
or
"Brian W. Kernighan".
The term is accompanied by zero or more attributes, each of which is a triple represented by a reference to a three-element array. Each such array consists of an attribute set identifier which may be either an OID or a short descriptive string, an integer type, and a value which may be either an integer or a string.
RsetNodeRepresents a result-set node, a reference to the name of a prior result set. The result-set name is accompanied by zero or more attributes as above.
AndNodeRepresents an AND node with two sub-nodes.
OrNodeRepresents an OR node with two sub-nodes.
NotNodeRepresents a NOT node with two sub-nodes. In the Z39.50 Type-1 query, and hence in PQF, NOT is a binary AND-NOT operator rather than than a unary negation operator.
ProxNodeRepresents a proximity node with two subnodes and five parameters:
exclusion: a boolean indicating whether the condition indicated by the other parameters should be inverted.
distance: an integer indicating the number of units that may separate the fragments identified by the subnodes.
ordered: a boolean indicating whether the elements indicated by the subnodes are constrained to be in the same order as the subnodes themselves.
relation: indicates the relation required on the specified distance in order for the condition to be satisfied.
unit:
a short string indicating the units of proximity (word,
sentence, etc.)
Except where noted, the methods described below are defined for all of the concrete node types.
$term1 = new Net::Z3950::PQF::TermNode('brian', [ "bib-1", 1, 1003 ]);
$term2 = new Net::Z3950::PQF::TermNode('unix', [ "bib-1", 1, 4 ]);
$and = new Net::Z3950::PQF::AndNode($term1, $term2);
Creates a new node object of the appropriate type. It is not possible
to instantiate the abstract node type, Net::Z3950::PQF::Node, only its
concrete subclasses.
The parameters required are different for different node types:
TermNodeThe first parameter is the actual term, and the remainder are attributes, each represented by a triple of [ attribute-set, type, value ].
AndNode, OrNode, NotNodeThe two parameters are nodes representing the subtrees.
ProxNodeThe seven parameters are, in order: the two nodes representing the subtrees, and the five parameters exclusion, distance, ordered, relation and unit.
$node->render(0);
Renders the contents of the tree rooted at the specified node, indented to a level indicated by the parameter. This output is in a human-readable form that is useful for debugging but probably not much else.
$node->toSimpleServer();
Transforms the contents of the tree rooted at the specified node, returning a correpsonding tree of the Perl structures produced by the Net::Z3950::SimpleServer module and passed as the {RPN} argument to search handlers. This emulation is useful for testing code that expects to receive queries in that format.
This module is part of the Net::Z3950::PQF distribution. The copyright, authorship and licence are all as for the distribution.
| Net-Z3950-PQF documentation | Contained in the Net-Z3950-PQF distribution. |
# $Id: Node.pm,v 1.4 2007/10/05 12:13:05 mike Exp $ package Net::Z3950::PQF::Node; use strict; use warnings;
sub new { my $class = shift(); die "can't create an abstract $class"; }
sub render { my $class = shift(); die "can't render an abstract $class"; }
sub toSimpleServer { my $class = shift(); die "can't translate an abstract $class into SimpleServer form"; } # PRIVATE base class, used as base by TermNode and RsetNode package Net::Z3950::PQF::LeafNode; our @ISA = qw(Net::Z3950::PQF::Node); sub new { my $class = shift(); my($value, @attrs) = @_; return bless { value => $value, attrs => [ @attrs ], }, $class; } sub render { my $this = shift(); my($level) = @_; die "render() called with no level" if !defined $level; my $text = ("\t" x $level) . $this->_name() . ": " . $this->{value} . "\n"; foreach my $attr (@{ $this->{attrs} }) { my($set, $type, $val) = @$attr; $text .= ("\t" x ($level+1)) . "attr: $set $type=$val\n"; } return $text; } sub toSimpleServer { my $this = shift(); my $attrs = bless [], "Net::Z3950::RPN::Attributes"; foreach my $attr (@{ $this->{attrs} }) { my($set, $type, $val) = @$attr; push @$attrs, bless { attributeSet => $set, attributeType => $type, attributeValue => $val, }, "Net::Z3950::RPN::Attribute"; } return bless { $this->_ssname() => $this->{value}, attributes => $attrs, }, $this->_ssclass(); } package Net::Z3950::PQF::TermNode; our @ISA = qw(Net::Z3950::PQF::LeafNode); sub _name { "term" } sub _ssname { "term" } sub _ssclass { "Net::Z3950::RPN::Term" } package Net::Z3950::PQF::RsetNode; our @ISA = qw(Net::Z3950::PQF::LeafNode); sub _name { "rset" } sub _ssname { "id" } sub _ssclass { "Net::Z3950::RPN::RSID" } # PRIVATE class, used as base by AndNode, OrNode and NotNode package Net::Z3950::PQF::BooleanNode; our @ISA = qw(Net::Z3950::PQF::Node); sub new { my $class = shift(); my(@sub) = @_; return bless { sub => [ @sub ], }, $class; } sub render { my $this = shift(); my($level) = @_; die "render() called with no level" if !defined $level; my $text = ("\t" x $level) . $this->_op() . "\n"; foreach my $sub (@{ $this->{sub} }) { $text .= $sub->render($level+1); } return $text; } sub toSimpleServer { my $this = shift(); my $res; foreach my $sub (@{ $this->{sub} }) { push @$res, $sub->toSimpleServer(); } return bless $res, $this->_ssclass(); } package Net::Z3950::PQF::AndNode; our @ISA = qw(Net::Z3950::PQF::BooleanNode); sub _op { "and" } sub _ssclass { "Net::Z3950::RPN::And" } package Net::Z3950::PQF::OrNode; our @ISA = qw(Net::Z3950::PQF::BooleanNode); sub _op { "or" } sub _ssclass { "Net::Z3950::RPN::Or" } package Net::Z3950::PQF::NotNode; our @ISA = qw(Net::Z3950::PQF::BooleanNode); sub _op { "not" } sub _ssclass { "Net::Z3950::RPN::AndNote" } package Net::Z3950::PQF::ProxNode; sub new { my $class = shift(); die "### class $class not yet implemented"; } sub render { my $this = shift(); die "you shouldn't have been able to make $this"; }
1;