(* Yaxi - Yet Another X* Implementation
 * Copyright (C) 2003 Matthieu Sozeau
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 * 
 * $Id: yaxi_xpath.mli,v 1.11 2003/11/02 16:56:46 mat Exp $
 * 
 *)

(** 
  XPath types and related functions
*)

exception XPathError of string;;

(** XPath primary objects types *)
type primary_type =
    Literal of string
  | Number of float
  | Boolean of bool
  | Nodes of Yaxi_xml.nodeset

(** A non parsed qname 
  prefix, localname
*)
and xpath_name = Yaxi_xml.ncname * Yaxi_xml.ncname 
    
(** Variable, value pair *)
and variable_binding = Yaxi_xml.qname * primary_type

(** Variables set *)
and variable_bindings = variable_binding list

(** XPath context used during evaluation *)
and eval_context = {
  mutable node : Yaxi_xml.node;  (** The context node *)
  mutable size : int;            (** The context node-set size *)
  mutable position : int;        (** The context node's position in the node-set *)
} 

(** XPath global context (not modified during evaluation *)
and global_context = {
  mutable variables : variable_bindings;                                (** Variable bindings *)
  mutable namespaces : Yaxi_xml.ns_mapping list;                             (** Namespace bindings *)
  mutable library : library;      (** Function library *)
} 
and library = (Yaxi_xml.qname * xpath_function) list

(** Type of XPath functions *)
and xpath_function = primary_type list -> xpath_expr
and xpath_expr = global_context -> eval_context -> primary_type

(** Axis *)
and axis =
  [ `Ancestor
  | `Ancestor_or_self
  | `Attribute
  | `Child
  | `Descendant
  | `Descendant_or_self
  | `Following
  | `Following_sibling
  | `Namespace
  | `Parent
  | `Preceding
  | `Preceding_sibling
  | `Self]

(** Node test *)
and node_test =
  [ `Anyp
  | `Commentp
  | `NameTest of xpath_name (* Qnames are parsed at runtime (within a context) *)
  | `Nodep
  | `ProcessingInstructionp of string option
  | `Rootp
  | `Textp]

(** XPath operators *)
and operator = 
  [ `Union 
  | `Add
  | `Sub
  | `Mul
  | `Div
  | `Mod
  | `And
  | `Or
  | `Not
  | `Equal
  | `InEqual 
  | `InfEqual
  | `SupEqual
  | `Sup
  | `Inf
  | `Minus
  ]
    
(** Expression *)
and expression =
  [ `Funcall of xpath_name * expression list
  | `Operation of operator * expression * expression
  | `UnaryOperation of operator * expression
  | `Primary of primary_type
  | `Steps of [`Relative | `Absolute] * steps
  | `Filter of expression * expression
  | `Variable of xpath_name]

(** XPath step *)
and step = axis * node_test * expression list

(** step list *)
and steps = step list

(** Type predicates *)
val booleanp : primary_type -> bool
val literalp : primary_type -> bool
val numberp : primary_type -> bool
val nodesp : primary_type -> bool

(** *)
val axis_of_axisname : string -> axis

val nodetest_of_str : string -> node_test

(** Get an (unparsed namespace prefix, ncname) pair from a string
  A name without prefix will get a null string prefix
*)
val parse_name : string -> xpath_name

(** Creates a new eval context of only one node *)
val new_context : Yaxi_xml.node -> int -> int -> eval_context

(** Set the variable bindings of a context *)
val context_set_variables : global_context -> variable_bindings -> unit

(** Adds a namespace mapping to the context *)
val context_add_ns : global_context -> Yaxi_xml.ns_mapping -> unit

(** Creates a new global context, adding some variable bindings 
  deprecated: use *)
val global_context_mutate : global_context -> variable_bindings -> global_context

(** Copy a context *)
val context_copy : global_context -> global_context

(** Add a variable binding to the context *)
val context_add_variable : global_context -> variable_binding -> unit

(** Do a binding exist ? *)
val context_has_variable : global_context -> Yaxi_xml.qname -> bool

(** Get the variable named qname or raise Not_found *)
val context_get_variable : global_context -> Yaxi_xml.qname -> primary_type

val string_of_operator : operator -> string
