]> matita.cs.unibo.it Git - helm.git/blob - helm/DEVEL/pxp/pxp/pxp_document.mli
- New interface for the MathQL interpreter (1.3 version)
[helm.git] / helm / DEVEL / pxp / pxp / pxp_document.mli
1 (* $Id$
2  * ----------------------------------------------------------------------
3  * PXP: The polymorphic XML parser for Objective Caml.
4  * Copyright by Gerd Stolpmann. See LICENSE for details.
5  *)
6
7 (**********************************************************************)
8 (*                                                                    *)
9 (* Pxp_document:                                                      *)
10 (*     Object model of the document/element instances                 *)
11 (*                                                                    *)
12 (**********************************************************************)
13
14
15 (* ======================================================================
16  * OVERVIEW
17  *
18  * class type node ............. The common class type of the nodes of
19  *                               the element tree. Nodes are either
20  *                               elements (inner nodes) or data nodes
21  *                               (leaves)
22  * class type extension ........ The minimal properties of the so-called
23  *                               extensions of the nodes: Nodes can be
24  *                               customized by applying a class parameter
25  *                               that adds methods/values to nodes.
26  * class data_impl : node ...... Implements data nodes.
27  * class element_impl : node ... Implements element nodes
28  * class document .............. A document is an element with some additional
29  *                               properties
30  *
31  * ======================================================================
32  *
33  * THE STRUCTURE OF NODE TREES:
34  *
35  * Every node except the root node has a parent node. The parent node is
36  * always an element, because data nodes never contain other nodes.
37  * In the other direction, element nodes may have children; both elements
38  * and data nodes are possible as children.
39  * Every node knows its parent (if any) and all its children (if any);
40  * the linkage is maintained in both directions. A node without a parent
41  * is called a root.
42  * It is not possible that a node is the child of two nodes (two different nodes
43  * or a multiple child of the same node).
44  * You can break the connection between a node and its parent; the method
45  * "delete" performs this operations and deletes the node from the parent's
46  * list of children. The node is now a root, for itself and for all
47  * subordinate nodes. In this context, the node is also called an orphan,
48  * because it has lost its parent (this is a bit misleading because the
49  * parent is not always the creator of a node).
50  * In order to simplify complex operations, you can also set the list of
51  * children of an element. Nodes that have been children before are unchanged;
52  * new nodes are added (and the linkage is set up), nodes no more occurring
53  * in the list are handled if they have been deleted.
54  * If you try to add a node that is not a root (either by an "add" or by a
55  * "set" operation) the operation fails.
56  *
57  * CREATION OF NODES
58  *
59  * The class interface supports creation of nodes by cloning a so-called
60  * exemplar. The idea is that it is sometimes useful to implement different
61  * element types by different classes, and to implement this by looking up
62  * exemplars.
63  * Imagine you have three element types A, B, and C, and three classes
64  * a, b, and c implementing the node interface (for example, by providing
65  * different extensions, see below). The XML parser can be configured to
66  * have a lookup table
67  *   { A --> a0,  B --> b0, C --> c0 }
68  * where a0, b0, c0 are exemplars of the classes a, b, and c, i.e. empty
69  * objects belonging to these classes. If the parser finds an instance of
70  * A, it looks up the exemplar a0 of A and clones it (actually, the method
71  * "create_element" performs this for elements, and "create_data" for data
72  * nodes). Clones belong to the same class as the original nodes, so the
73  * instances of the elements have the same classes as the configured
74  * exemplars.
75  * Note: This technique assumes that the interface of all exemplars is the
76  * same!
77  *
78  * THE EXTENSION
79  *
80  * The class type node and all its implementations have a class parameter
81  * 'ext which must at least fulfil the properties of the class type "extension".
82  * The idea is that you can add properties, for example:
83  *
84  * class my_extension =
85  *   object
86  *     (* minimal properties required by class type "extension": *)
87  *     method clone = ...
88  *     method node = ...
89  *     method set_node n = ...
90  *     (* here my own methods: *)
91  *     method do_this_and_that ...
92  *   end
93  *
94  * class my_element_impl = [ my_extension ] element_impl
95  * class my_data_impl    = [ my_extension ] data_impl
96  *
97  * The whole XML parser is parameterized with 'ext, so your extension is
98  * visible everywhere (this is the reason why extensibility is solved by
99  * parametric polymorphism and not by inclusive polymorphism (subtyping)).
100  *
101  *
102  * SOME COMPLICATED TYPE EXPRESSIONS
103  *
104  * Sometimes the following type expressions turn out to be necessary:
105  *
106  * 'a node extension as 'a
107  *      This is the type of an extension that belongs to a node that
108  *      has an extension that is the same as we started with.
109  *
110  * 'a extension node as 'a
111  *      This is the type of a node that has an extension that belongs to a
112  *      node of the type we started with.
113  *
114  *
115  * DOCUMENTS
116  * ...
117  *
118  * ======================================================================
119  *
120  * SIMPLE USAGE: ...
121  *)
122
123
124 open Pxp_dtd
125
126
127 type node_type =
128   (* The basic and most important node types:
129    * - T_element element_type   is the type of element nodes
130    * - T_data                   is the type of text data nodes
131    * By design of the parser, neither CDATA sections nor entity references
132    * are represented in the node tree; so there are no types for them.
133    *)
134     T_element of string
135   | T_data
136
137   (* The following types are extensions to my original design. They have mainly
138    * been added to simplify the implementation of standards (such as
139    * XPath) that require that nodes of these types are included into the
140    * main document tree.
141    * There are options (see Pxp_yacc) forcing the parser to insert such
142    * nodes; in this case, the nodes are actually element nodes serving
143    * as wrappers for the additional data structures. The options are:
144    * enable_super_root_node, enable_pinstr_nodes, enable_comment_nodes.
145    * By default, such nodes are not created.
146    *)
147   | T_super_root
148   | T_pinstr of string                  (* The string is the target of the PI *)
149   | T_comment
150
151   (* The following types are fully virtual. This means that it is impossible
152    * to make the parser insert such nodes. However, these types might be
153    * practical when defining views on the tree.
154    * Note that the list of virtual node types will be extended if necessary.
155    *)
156   | T_none
157   | T_attribute of string          (* The string is the name of the attribute *)
158   | T_namespace of string               (* The string is the namespace prefix *)
159 ;;
160
161
162 class type [ 'node ] extension =
163   object ('self)
164     method clone : 'self
165       (* "clone" should return an exact deep copy of the object. *)
166     method node : 'node
167       (* "node" returns the corresponding node of this extension. This method
168        * intended to return exactly what previously has been set by "set_node".
169        *)
170     method set_node : 'node -> unit
171       (* "set_node" is invoked once the extension is associated to a new
172        * node object.
173        *)
174   end
175 ;;
176
177
178 class type [ 'ext ] node =
179   object ('self)
180     constraint 'ext = 'ext node #extension
181
182     method extension : 'ext
183       (* Return the extension of this node: *)
184
185     method delete : unit
186       (* Delete this node from the parent's list of sub nodes. This node gets
187        * orphaned.
188        * 'delete' does nothing if this node does not have a parent.
189        *)
190
191     method parent : 'ext node
192       (* Get the parent, or raise Not_found if this node is an orphan. *)
193
194     method root : 'ext node
195       (* Get the direct or indirect parent that does not have a parent itself,
196        * i.e. the root of the tree.
197        *)
198
199     method orphaned_clone : 'self
200       (* return an exact clone of this element and all sub nodes (deep copy)
201        * except string values which are shared by this node and the clone.
202        * The other exception is that the clone has no parent (i.e. it is now
203        * a root).
204        *)
205
206     method orphaned_flat_clone : 'self
207       (* return a clone of this element where all subnodes are omitted.
208        * The type of the node, and the attributes are the same as in the
209        * original node.
210        * The clone has no parent.
211        *)
212
213     method add_node : ?force:bool -> 'ext node -> unit
214       (* Append new sub nodes -- mainly used by the parser itself, but
215        * of course open for everybody. If an element is added, it must be
216        * an orphan (i.e. does not have a parent node); and after addition
217        * *this* node is the new parent.
218        * The method performs some basic validation checks if the current node
219        * has a regular expression as content model, or is EMPTY. You can
220        * turn these checks off by passing ~force:true to the method.
221        *)
222
223     method add_pinstr : proc_instruction -> unit
224       (* Add a processing instruction to the set of processing instructions of
225        * this node. Usually only elements contain processing instructions.
226        *)
227
228     method pinstr : string -> proc_instruction list
229       (* Get all processing instructions with the passed name *)
230
231     method pinstr_names : string list
232       (* Get a list of all names of processing instructions *)
233
234     method node_position : int
235       (* Returns the position of this node among all children of the parent
236        * node. Positions are counted from 0.
237        * Raises Not_found if the node is the root node.
238        *)
239
240     method node_path : int list
241       (* Returns the list of node positions of the ancestors of this node,
242        * including this node. The first list element is the node position
243        * of this child of the root, and the last list element is the 
244        * node position of this node.
245        * Returns [] if the node is the root node.
246        *)
247
248     method sub_nodes : 'ext node list
249       (* Get the list of sub nodes *)
250
251     method iter_nodes : ('ext node -> unit) -> unit
252       (* iterate over the sub nodes *)
253
254     method iter_nodes_sibl :
255       ('ext node option -> 'ext node -> 'ext node option -> unit) -> unit
256       (* Here every iteration step can also access to the previous and to the
257        * following node if present.
258        *)
259
260     method nth_node : int -> 'ext node
261       (* Returns the n-th sub node of this node, n >= 0. Raises Not_found
262        * if the index is out of the valid range.
263        * Note that the first invocation of this method requires additional
264        * overhead.
265        *)
266
267     method previous_node : 'ext node
268     method next_node : 'ext node
269       (* Return the previous and next nodes, respectively. These methods are
270        * equivalent to 
271        * - parent # nth_node (self # node_position - 1) and
272        * - parent # nth_node (self # node_position + 1), respectively.
273        *)
274
275     method set_nodes : 'ext node list -> unit
276       (* Set the list of sub nodes. Elements that are no longer sub nodes gets
277        * orphaned, and all new elements that previously were not sub nodes
278        * must have been orphaned.
279        *)
280
281     method data : string
282       (* Get the data string of this node. For data nodes, this string is just
283        * the content. For elements, this string is the concatenation of all
284        * subordinate data nodes.
285        *)
286
287     method node_type : node_type
288       (* Get the name of the element type. *)
289
290     method position : (string * int * int)
291       (* Return the name of the entity, the line number, and the column
292        * position (byte offset) of the beginning of the element.
293        * Only available if the element has been created with position
294        * information.
295        * Returns "?",0,0 if not available. (Note: Line number 0 is not
296        * possible otherwise.)
297        *)
298
299     method attribute : string -> Pxp_types.att_value
300     method attribute_names : string list
301     method attribute_type : string -> Pxp_types.att_type
302     method attributes : (string * Pxp_types.att_value) list
303       (* Get a specific attribute; get the names of all attributes; get the
304        * type of a specific attribute; get names and values of all attributes.
305        * Only elements have attributes.
306        * Note: If the DTD allows arbitrary for this element, "attribute_type"
307        * raises Undeclared.
308        *)
309
310     method required_string_attribute : string -> string
311     method required_list_attribute : string -> string list
312       (* Return the attribute or fail if the attribute is not present:
313        * The first version passes the value always as string back;
314        * the second version always as list.
315        *)
316
317     method optional_string_attribute : string -> string option
318     method optional_list_attribute : string -> string list
319       (* Return some attribute value or return None if the attribute is not
320        *  present:
321        * The first version passes the value always as string back;
322        * the second version always as list.
323        *)
324
325     method id_attribute_name : string
326     method id_attribute_value : string
327       (* Return the name and value of the ID attribute. The methods may
328        * raise Not_found if there is no ID attribute in the DTD, or no
329        * ID attribute in the element, respectively.
330        *)
331
332     method idref_attribute_names : string list
333       (* Returns the list of attribute names of IDREF or IDREFS type. *)
334
335     method quick_set_attributes : (string * Pxp_types.att_value) list -> unit
336       (* Sets the attributes but does not check whether they match the DTD.
337        *)
338
339     method attributes_as_nodes : 'ext node list
340       (* Experimental feature: Return the attributes as node list. Every node
341        * has type T_attribute n, and contains only the single attribute n.
342        * This node list is computed on demand, so the first invocation of this
343        * method will create the list, and following invocations will only
344        * return the existing list.
345        *)
346
347     method set_comment : string option -> unit
348       (* Sets the comment string; only applicable for T_comment nodes *)
349
350     method comment : string option
351       (* Get the comment string.
352        * Returns always None for nodes with a type other than T_comment.
353        *)
354
355     method dtd : dtd
356       (* Get the DTD. Fails if no DTD is specified (which is impossible if
357        * 'create_element' or 'create_data' have been used to create this
358        * object)
359        *)
360
361     method encoding : Pxp_types.rep_encoding
362       (* Get the encoding which is always the same as the encoding of the
363        * DTD. See also method 'dtd' (Note: This method fails, too, if
364        * no DTD is present.)
365        *)
366
367     method create_element : 
368              ?position:(string * int * int) ->
369              dtd -> node_type -> (string * string) list -> 'ext node
370       (* create an "empty copy" of this element:
371        * - new DTD
372        * - new node type (which must not be T_data)
373        * - new attribute list
374        * - empty list of nodes
375        *)
376
377     method create_data : dtd -> string -> 'ext node
378       (* create an "empty copy" of this data node: *)
379
380     method local_validate : 
381              ?use_dfa:bool ->
382              unit -> unit
383       (* Check that this element conforms to the DTD. 
384        * Option ~use_dfa: If true, the deterministic finite automaton of
385        *   regexp content models is used for validation, if available.
386        *   Defaults to false.
387        *)
388
389     method keep_always_whitespace_mode : unit
390       (* Normally, add_node does not accept data nodes when the DTD does not
391        * allow data nodes or only whitespace ("ignorable whitespace").
392        * Once you have invoked this method, ignorable whitespace is forced
393        * to be included into the document.
394        *)
395
396     method write : Pxp_types.output_stream -> Pxp_types.encoding -> unit
397       (* Write the contents of this node and the subtrees to the passed
398        * output stream; the passed encoding is used. The format
399        * is compact (the opposite of "pretty printing").
400        *)
401
402     method write_compact_as_latin1 : Pxp_types.output_stream -> unit
403       (* DEPRECATED METHOD; included only to keep compatibility with
404        * older versions of the parser
405        *)
406
407
408     (* ---------------------------------------- *)
409     (* The methods 'find' and 'reset_finder' are no longer supported.
410      * The functionality is provided by the configurable index object
411      * (see Pxp_yacc).
412      *)
413
414
415     (* ---------------------------------------- *)
416     (* internal methods: *)
417     method internal_adopt : 'ext node option -> int -> unit
418     method internal_set_pos : int -> unit
419     method internal_delete : 'ext node -> unit
420     method internal_init : (string * int * int) ->
421                            dtd -> string -> (string * string) list -> unit
422     method internal_init_other : (string * int * int) ->
423                                  dtd -> node_type -> unit
424   end
425 ;;
426
427
428 class [ 'ext ] data_impl : 'ext -> [ 'ext ] node
429     (* Creation:
430      *   new data_impl an_extension
431      * creates a new data node with the given extension and the empty string
432      * as content.
433      *)
434 ;;
435
436
437 class [ 'ext ] element_impl : 'ext -> [ 'ext ] node
438     (* Creation:
439      *   new element_impl an_extension
440      * creates a new empty element node with the given extension.
441      *)
442 ;;
443
444
445 (* Attribute and namespace nodes are experimental: *)
446
447 class [ 'ext ] attribute_impl : 
448   element:string -> name:string -> Pxp_types.att_value -> dtd -> [ 'ext ] node
449
450     (* Creation:
451      *   new attribute_impl element_name attribute_name attribute_value dtd
452      * Note that attribute nodes do intentionally not have extensions.
453      *)
454
455 (* Once namespaces get implemented:
456 class [ 'ext ] namespace_impl : 
457   prefix:string -> name:string -> dtd -> [ 'ext ] node
458 *)
459
460 (********************************** spec *********************************)
461
462 type 'ext spec
463 constraint 'ext = 'ext node #extension
464     (* Contains the exemplars used for the creation of new nodes
465      *)
466
467
468 val make_spec_from_mapping :
469       ?super_root_exemplar : 'ext node ->
470       ?comment_exemplar : 'ext node ->
471       ?default_pinstr_exemplar : 'ext node ->
472       ?pinstr_mapping : (string, 'ext node) Hashtbl.t ->
473       data_exemplar: 'ext node ->
474       default_element_exemplar: 'ext node ->
475       element_mapping: (string, 'ext node) Hashtbl.t -> 
476       unit -> 
477         'ext spec
478     (* Specifies:
479      * - For new data nodes, the ~data_exemplar must be used
480      * - For new element nodes: If the element type is mentioned in the
481      *   ~element_mapping hash table, the exemplar found in this table is
482      *   used. Otherwise, the ~default_element_exemplar is used.
483      * Optionally:
484      * - You may also specify exemplars for super root nodes, for comments
485      *   and for processing instructions
486      *)
487
488 val make_spec_from_alist :
489       ?super_root_exemplar : 'ext node ->
490       ?comment_exemplar : 'ext node ->
491       ?default_pinstr_exemplar : 'ext node ->
492       ?pinstr_alist : (string * 'ext node) list ->
493       data_exemplar: 'ext node ->
494       default_element_exemplar: 'ext node ->
495       element_alist: (string * 'ext node) list -> 
496       unit -> 
497         'ext spec
498     (* This is a convenience function: You can pass the mappings from 
499      * elements and PIs to exemplar by associative lists.
500      *)
501
502 val create_data_node : 
503       'ext spec -> dtd -> string -> 'ext node
504 val create_element_node : 
505       ?position:(string * int * int) ->
506       'ext spec -> dtd -> string -> (string * string) list -> 'ext node
507 val create_super_root_node :
508       ?position:(string * int * int) ->
509       'ext spec -> dtd -> 'ext node
510 val create_comment_node :
511       ?position:(string * int * int) ->
512       'ext spec -> dtd -> string -> 'ext node
513 val create_pinstr_node :
514       ?position:(string * int * int) ->
515       'ext spec -> dtd -> proc_instruction -> 'ext node
516   (* These functions use the exemplars contained in a spec and create fresh
517    * node objects from them.
518    *)
519
520 val create_no_node : 
521        ?position:(string * int * int) -> 'ext spec -> dtd -> 'ext node
522   (* Creates a T_none node with limited functionality *)
523
524 (*********************** Ordering of nodes ******************************)
525
526 val compare : 'ext node -> 'ext node -> int
527   (* Returns -1 if the first node is before the second node, or +1 if the
528    * first node is after the second node, or 0 if both nodes are identical.
529    * If the nodes are unrelated (do not have a common ancestor), the result
530    * is undefined.
531    * This test is rather slow.
532    *)
533
534 type 'ext ord_index
535 constraint 'ext = 'ext node #extension
536   (* The type of ordinal indexes *)
537
538 val create_ord_index : 'ext node -> 'ext ord_index
539   (* Creates an ordinal index for the subtree starting at the passed node.
540    * This index assigns to every node an ordinal number (beginning with 0) such
541    * that nodes are numbered upon the order of the first character in the XML
542    * representation (document order).
543    * Note that the index is not automatically updated when the tree is
544    * modified.
545    *)
546
547 val ord_number : 'ext ord_index -> 'ext node -> int
548   (* Returns the ordinal number of the node, or raises Not_found *)
549
550 val ord_compare : 'ext ord_index -> 'ext node -> 'ext node -> int
551   (* Compares two nodes like 'compare':
552    * Returns -1 if the first node is before the second node, or +1 if the
553    * first node is after the second node, or 0 if both nodes are identical.
554    * If one of the nodes does not occur in the ordinal index, Not_found
555    * is raised.
556    * This test is much faster than 'compare'.
557    *)
558
559
560 (***************************** Iterators ********************************)
561
562 val find : ?deeply:bool -> 
563            f:('ext node -> bool) -> 'ext node -> 'ext node
564   (* Searches the first node for which the predicate f is true, and returns
565    * it. Raises Not_found if there is no such node.
566    * By default, ~deeply=false. In this case, only the children of the
567    * passed node are searched.
568    * If passing ~deeply=true, the children are searched recursively
569    * (depth-first search).
570    *)
571
572 val find_all : ?deeply:bool ->
573                f:('ext node -> bool) -> 'ext node -> 'ext node list
574   (* Searches all nodes for which the predicate f is true, and returns them.
575    * By default, ~deeply=false. In this case, only the children of the
576    * passed node are searched.
577    * If passing ~deeply=true, the children are searched recursively
578    * (depth-first search).
579    *)
580
581 val find_element : ?deeply:bool ->
582                    string -> 'ext node -> 'ext node
583   (* Searches the first element with the passed element type.
584    * By default, ~deeply=false. In this case, only the children of the
585    * passed node are searched.
586    * If passing ~deeply=true, the children are searched recursively
587    * (depth-first search).
588    *)
589
590 val find_all_elements : ?deeply:bool ->
591                         string -> 'ext node -> 'ext node list
592   (* Searches all elements with the passed element type.
593    * By default, ~deeply=false. In this case, only the children of the
594    * passed node are searched.
595    * If passing ~deeply=true, the children are searched recursively
596    * (depth-first search).
597    *)
598
599 exception Skip
600 val map_tree :  pre:('exta node -> 'extb node) ->
601                ?post:('extb node -> 'extb node) ->
602                'exta node -> 
603                    'extb node
604   (* Traverses the passed node and all children recursively. After entering
605    * a node, the function ~pre is called. The result of this function must
606    * be a new node; it must not have children nor a parent (you can simply
607    * pass (fun n -> n # orphaned_flat_clone) as ~pre).
608    * After that, the children are processed in the same way (from left to
609    * right); the results of the transformation will be added to the
610    * new node as new children.
611    * Now, the ~post function is invoked with this node as argument, and
612    * the result is the result of the function (~post should return a root
613    * node, too; if not specified, the identity is the ~post function).
614    * Both ~pre and ~post may raise Skip, which causes that the node is
615    * left out. If the top node is skipped, the exception Not_found is
616    * raised.
617    *)
618
619 val map_tree_sibl : 
620         pre: ('exta node option -> 'exta node -> 'exta node option -> 
621                   'extb node) ->
622        ?post:('extb node option -> 'extb node -> 'extb node option -> 
623                   'extb node) ->
624        'exta node -> 
625            'extb node
626    (* Works like map_tree, but the function ~pre and ~post have additional
627     * arguments:
628     * - ~pre l n r: The node n is the node to map, and l is the previous
629     *   node, and r is the next node (both None if not present). l and r
630     *   are both nodes before the transformation.
631     * - ~post l n r: The node n is the node which is the result of ~pre
632     *   plus adding children. l and r are again the previous and the next
633     *   node, respectively, but after being transformed.
634     *)
635
636 val iter_tree : ?pre:('ext node -> unit) ->
637                 ?post:('ext node -> unit) ->
638                 'ext node -> 
639                     unit
640    (* Iterates only instead of mapping the nodes. *)
641
642 val iter_tree_sibl :
643        ?pre: ('ext node option -> 'ext node -> 'ext node option -> unit) ->
644        ?post:('ext node option -> 'ext node -> 'ext node option -> unit) ->
645        'ext node -> 
646            unit
647    (* Iterates only instead of mapping the nodes. *)
648
649
650 (******************************* document ********************************)
651
652
653 class [ 'ext ] document :
654   Pxp_types.collect_warnings -> 
655   object
656     (* Documents: These are containers for root elements and for DTDs.
657      * 
658      * Important invariant: A document is either empty (no root element,
659      * no DTD), or it has both a root element and a DTD.
660      *
661      * A fresh document created by 'new' is empty.
662      *)
663
664     method init_xml_version : string -> unit
665         (* Set the XML version string of the XML declaration. *)
666
667     method init_root : 'ext node -> unit
668         (* Set the root element. It is expected that the root element has
669          * a DTD.
670          * Note that 'init_root' checks whether the passed root element
671          * has the type expected by the DTD. The check takes into account
672          * that the root element might be a virtual root node.
673          *)
674
675     method xml_version : string
676       (* Returns the XML version from the XML declaration. Returns "1.0"
677        * if the declaration is missing.
678        *)
679
680     method xml_standalone : bool
681       (* Returns whether this document is declared as being standalone.
682        * This method returns the same value as 'standalone_declaration'
683        * of the DTD (if there is a DTD).
684        * Returns 'false' if there is no DTD.
685        *)
686
687     method dtd : dtd
688       (* Returns the DTD of the root element. 
689        * Fails if there is no root element.
690        *)
691
692     method encoding : Pxp_types.rep_encoding
693       (* Returns the string encoding of the document = the encoding of
694        * the root element = the encoding of the element tree = the
695        * encoding of the DTD.
696        * Fails if there is no root element.
697        *)
698
699     method root : 'ext node
700       (* Returns the root element, or fails if there is not any. *)
701
702     method add_pinstr : proc_instruction -> unit
703       (* Adds a processing instruction to the document container.
704        * The parser does this for PIs occurring outside the DTD and outside
705        * the root element.
706        *)
707
708     method pinstr : string -> proc_instruction list
709       (* Return all PIs for a passed target string. *)
710
711     method pinstr_names : string list
712       (* Return all target strings of all PIs. *)
713
714     method write : Pxp_types.output_stream -> Pxp_types.encoding -> unit
715       (* Write the document to the passed
716        * output stream; the passed encoding used. The format
717        * is compact (the opposite of "pretty printing").
718        * If a DTD is present, the DTD is included into the internal subset.
719        *)
720
721     method write_compact_as_latin1 : Pxp_types.output_stream -> unit
722       (* DEPRECATED METHOD; included only to keep compatibility with
723        * older versions of the parser
724        *)
725
726   end
727 ;;
728
729
730 (* ======================================================================
731  * History:
732  *
733  * $Log$
734  * Revision 1.1  2000/11/17 09:57:29  lpadovan
735  * Initial revision
736  *
737  * Revision 1.10  2000/08/30 15:47:37  gerd
738  *      New method node_path.
739  *      New function compare.
740  *      New type ord_index with functions.
741  *
742  * Revision 1.9  2000/08/26 23:27:53  gerd
743  *      New function: make_spec_from_alist.
744  *      New iterators: find, find_all, find_element, find_all_elements,
745  * map_tree, map_tree_sibl, iter_tree, iter_tree_sibl.
746  *      New node methods: node_position, nth_node, previous_node,
747  * next_node.
748  *      Attribute and namespace types have now a string argument:
749  * the name/prefix. I hope this simplifies the handling of view nodes.
750  *      First implementation of view nodes: attribute_impl. The
751  * method attributes_as_nodes returns the attributes wrapped into
752  * T_attribute nodes which reside outside the document tree.
753  *
754  * Revision 1.8  2000/08/18 20:14:00  gerd
755  *      New node_types: T_super_root, T_pinstr, T_comment, (T_attribute),
756  * (T_none), (T_namespace).
757  *
758  * Revision 1.7  2000/07/23 02:16:34  gerd
759  *      Support for DFAs.
760  *
761  * Revision 1.6  2000/07/16 16:34:41  gerd
762  *      New method 'write', the successor of 'write_compact_as_latin1'.
763  *
764  * Revision 1.5  2000/07/14 13:56:11  gerd
765  *      Added methods id_attribute_name, id_attribute_value,
766  * idref_attribute_names.
767  *
768  * Revision 1.4  2000/07/09 17:51:14  gerd
769  *      Element nodes can store positions.
770  *
771  * Revision 1.3  2000/07/04 22:05:10  gerd
772  *      New functions make_spec_from_mapping, create_data_node,
773  * create_element_node.
774  *
775  * Revision 1.2  2000/06/14 22:19:06  gerd
776  *      Added checks such that it is impossible to mix encodings.
777  *
778  * Revision 1.1  2000/05/29 23:48:38  gerd
779  *      Changed module names:
780  *              Markup_aux          into Pxp_aux
781  *              Markup_codewriter   into Pxp_codewriter
782  *              Markup_document     into Pxp_document
783  *              Markup_dtd          into Pxp_dtd
784  *              Markup_entity       into Pxp_entity
785  *              Markup_lexer_types  into Pxp_lexer_types
786  *              Markup_reader       into Pxp_reader
787  *              Markup_types        into Pxp_types
788  *              Markup_yacc         into Pxp_yacc
789  * See directory "compatibility" for (almost) compatible wrappers emulating
790  * Markup_document, Markup_dtd, Markup_reader, Markup_types, and Markup_yacc.
791  *
792  * ======================================================================
793  * Old logs from markup_document.mli:
794  *
795  * Revision 1.13  2000/05/27 19:15:08  gerd
796  *      Removed the method init_xml_standalone.
797  *
798  * Revision 1.12  2000/05/01 20:42:34  gerd
799  *         New method write_compact_as_latin1.
800  *
801  * Revision 1.11  2000/04/30 18:15:57  gerd
802  *      Beautifications.
803  *      New method keep_always_whitespace_mode.
804  *
805  * Revision 1.10  2000/03/11 22:58:15  gerd
806  *      Updated to support Markup_codewriter.
807  *
808  * Revision 1.9  2000/01/27 21:51:56  gerd
809  *      Added method 'attributes'.
810  *
811  * Revision 1.8  2000/01/27 21:19:07  gerd
812  *      Added further methods.
813  *
814  * Revision 1.7  1999/11/09 22:20:14  gerd
815  *      Removed method init_dtd from class "document". The DTD is
816  * implicitly passed to the document by the root element.
817  *
818  * Revision 1.6  1999/09/01 22:51:40  gerd
819  *      Added methods to store processing instructions.
820  *
821  * Revision 1.5  1999/09/01 16:19:57  gerd
822  *      The "document" class has now a "warner" as class argument.
823  *
824  * Revision 1.4  1999/08/19 21:59:13  gerd
825  *      Added method "reset_finder".
826  *
827  * Revision 1.3  1999/08/19 01:08:29  gerd
828  *      Added method "find".
829  *
830  * Revision 1.2  1999/08/15 02:19:41  gerd
831  *      Some new explanations: That unknown elements are not rejected
832  * if the DTD allows them.
833  *
834  * Revision 1.1  1999/08/10 00:35:51  gerd
835  *      Initial revision.
836  *
837  *
838  *)