type _node 
type _atomic
type _rqname
type _uri

class virtual item :
object
  method virtual string_value : unit -> string
  method virtual item_kind : unit -> string
  method virtual getAtomic : unit -> _atomic
  method virtual getNode : unit -> _node
end

type value = item list 

class virtual atomicvalue :
object
 inherit item
 method item_kind : unit -> string
 method string_value : unit -> string
 method getNode : unit -> _node
 method virtual getAtomic : unit -> _atomic
end

class xs_QName : 
 (string * string) option * _atomic option ->
object
 inherit atomicvalue
 (* We should implement xs:QName-in-context *)
 method getAtomic : unit -> _atomic
 method uri : unit -> string
 method local_name : unit -> string
end

class xs_string : 
 string option * _atomic option ->
object
 inherit atomicvalue
 method getAtomic : unit -> _atomic
end

class xs_boolean : 
 bool  option * _atomic option ->
object
 inherit atomicvalue
 method getAtomic : unit -> _atomic
end

class xs_int : 
 int  option * _atomic option ->
object
 inherit atomicvalue
 method getAtomic : unit -> _atomic
end

class xs_integer : 
 int  option * _atomic option ->
object
 inherit atomicvalue
 method getAtomic : unit -> _atomic
end

class xs_decimal : 
 int  option * _atomic option ->
object
 inherit atomicvalue
 method getAtomic : unit -> _atomic
end

class xs_float : 
 float option * _atomic option ->
object
 inherit atomicvalue
 method getAtomic : unit -> _atomic
end

class xs_double : 
 float  option * _atomic option ->
object
 inherit atomicvalue
 method getAtomic : unit -> _atomic
end

class xs_anyURI : 
 string  option * _atomic option ->
object
 inherit atomicvalue
 method getAtomic : unit -> _atomic
end

class xs_untyped : 
 string  option * _atomic option ->
object
 inherit atomicvalue
 method getAtomic : unit -> _atomic
end

class virtual node :
(*  Datamodel._Node -> *)
object
 inherit item
 method getAtomic : unit -> _atomic
 method virtual getNode : unit -> _node
 method virtual item_kind : unit -> string
 method string_value : unit -> string
end
class document:
 node list option * _node option ->
object
 inherit node
 method item_kind : unit -> string
 method getNode : unit -> _node
end

class text:
 xs_string option * _node option ->
object
 inherit node
 method item_kind : unit -> string
 method getNode : unit -> _node
end

class attribute:
 (xs_QName * xs_string * xs_QName) option * _node option ->
object
 inherit node
 method item_kind : unit -> string
 method getNode : unit -> _node
end

class element:
 (xs_QName * attribute list * node list * xs_QName) option * _node option ->
object
 inherit node
 method item_kind : unit -> string
 method getNode : unit -> _node
end

class comment:
  xs_string option * _node option ->
object
 inherit node
 method item_kind : unit -> string
 method getNode : unit -> _node
end

class processing_instruction:
  (xs_string * xs_string) option * _node option ->
object
 inherit node
 method item_kind : unit -> string
 method getNode : unit -> _node
end

(* All the methods common to the node object are here: *)
val parent : node -> node list 
val children : node -> node list 
val string_value : node -> string 

val base_uri : node -> string 
val node_kind : node -> string 
val node_name : node -> xs_QName option
val typed_value : node -> value 
val attributes : node -> node list (* 0 or more node list *)
val namespace : node -> node list (* 0 or more node list *)

(** Everything up to here should go in datamodel_api.mli **)
(** Everything after here should go in galapi.mli **)

(****************************************)
(* Types to represent XQuery components *)
(****************************************)

type context
      (** Abstract type for a query context. It contains the following
          information:
           o Namespace declarations
           o User-defined functions
           o Global variables
           o Imported schemas *)

type compiled_context
      (** Same thing as a context, but compiled. *)

(***********************************)
(* Operations on the query context *)
(***********************************)

val default_context : context
    (** Default context. Contains:
         o built-in types
         o built-in functions *)
      
val build_context_from_file   : string -> context
    (** Creates a new context by loading an XQuery prolog from within a file *)

val build_context_from_string : string -> context
    (** Creates a new context by loading an XQuery prolog from within a string *)

val add_variable_binding_to_context : context -> string -> value -> context
    (** Adds a new global variable into a given context *)

(********************************)
(* Input / output of operations *)
(********************************)
val load_document : string -> node list
    (** [load_document filename] load the XML document from the file
        [filename] *)

val load_document_validate : context -> string -> node list 
    (** [load_document_validate context filename] load the XML
    document from the file [filename] and validate in [context] *)

val serialize_to_string : value -> string  
    (** [serializes_to_string x] serializes an XML value to a string *)

val serialize_to_output_channel : out_channel -> value -> unit
    (** [serializes_to_output_channel oc x] serializes an XML value to
        the output channel [oc] *)

val serialize_to_file : string -> value -> unit
    (** [serializes_to_file filename x] serializes an XML value to the
        file [filename] *)


(***********************)
(* Querying operations *)
(***********************)

type compiled_query_expr

type compiled_query = (compiled_context * compiled_query_expr list)

val compile_query_file : context -> string -> compiled_query

val eval_query_string : context -> value -> string -> value
  (** [eval_query_string context xml query]

       Given the context [context], evaluates the query [query] with
       the context item bound to the document fragment [xml].  *)

val eval_query_file : context -> value -> string -> value
  (** [eval_query_string context xml file]

       Given the context [context], evaluates the query in file [file]
       with the context item bound to the document fragment [xml].  *)

val eval_xquery_fun : context -> string -> value list -> value
  (** [eval_xquery_fun context fun_name params]

       Given the context [context], evaluates the function [fun_name]
       applied to arguments in [params].  *)

val eval_compiled_query_expr :
    compiled_context -> value -> compiled_query_expr -> value

val eval_compiled_query_expr_no_dot :
    compiled_context -> compiled_query_expr -> value

val xs_string :
   string -> xs_string
val xs_boolean :
   bool -> xs_boolean
val xs_integer :
   int -> xs_integer
val xs_int :
   int -> xs_int
val xs_decimal :
   int -> xs_decimal
val xs_float :
   float -> xs_float
val xs_double :
   float -> xs_double
val xs_anyURI :
   string -> xs_anyURI
val xs_untyped :
   string -> xs_untyped
val xs_QName :
   (string * string) -> xs_QName
val element :
 (xs_QName * attribute list * node list * xs_QName) ->  element
val text:
 xs_string -> text 
val attribute:
 (xs_QName * xs_string * xs_QName)  -> attribute
val comment:
  xs_string  -> comment
val processing_instruction:
  (xs_string * xs_string)  -> processing_instruction

val get_node      : item -> node
val get_atomicvalue : item -> atomicvalue
val get_element   : item -> element
val get_attribute : item -> attribute
val get_xs_string : item -> xs_string
