]> matita.cs.unibo.it Git - helm.git/blob - helm/DEVEL/pxp/pxp/compatibility/markup_document.mli
- the mathql interpreter is not helm-dependent any more
[helm.git] / helm / DEVEL / pxp / pxp / compatibility / markup_document.mli
1 (* $Id$
2  * ----------------------------------------------------------------------
3  * Markup! The validating XML parser for Objective Caml.
4  * Copyright 1999 by Gerd Stolpmann. See LICENSE for details.
5  *
6  * THIS IS THE markup-0.2.10 COMPATIBLE INTERFACE TO markup_document.mli.
7  * It corresponds to revision 1.13 of markup_document.mli.
8  *)
9
10 (**********************************************************************)
11 (*                                                                    *)
12 (* Markup_document:                                                   *)
13 (*     Object model of the document/element instances                 *)
14 (*                                                                    *)
15 (**********************************************************************)
16
17
18 (* ======================================================================
19  * OVERVIEW
20  *
21  * class type node ............. The common class type of the nodes of
22  *                               the element tree. Nodes are either
23  *                               elements (inner nodes) or data nodes
24  *                               (leaves)
25  * class type extension ........ The minimal properties of the so-called
26  *                               extensions of the nodes: Nodes can be
27  *                               customized by applying a class parameter
28  *                               that adds methods/values to nodes.
29  * class data_impl : node ...... Implements data nodes.
30  * class element_impl : node ... Implements element nodes
31  * class document .............. A document is an element with some additional
32  *                               properties
33  *
34  * ======================================================================
35  *
36  * THE STRUCTURE OF NODE TREES:
37  *
38  * Every node except the root node has a parent node. The parent node is
39  * always an element, because data nodes never contain other nodes.
40  * In the other direction, element nodes may have children; both elements
41  * and data nodes are possible as children.
42  * Every node knows its parent (if any) and all its children (if any);
43  * the linkage is maintained in both directions. A node without a parent
44  * is called a root.
45  * It is not possible that a node is the child of two nodes (two different nodes
46  * or a multiple child of the same node).
47  * You can break the connection between a node and its parent; the method
48  * "delete" performs this operations and deletes the node from the parent's
49  * list of children. The node is now a root, for itself and for all
50  * subordinate nodes. In this context, the node is also called an orphan,
51  * because it has lost its parent (this is a bit misleading because the
52  * parent is not always the creator of a node).
53  * In order to simplify complex operations, you can also set the list of
54  * children of an element. Nodes that have been children before are unchanged;
55  * new nodes are added (and the linkage is set up), nodes no more occurring
56  * in the list are handled if they have been deleted.
57  * If you try to add a node that is not a root (either by an "add" or by a
58  * "set" operation) the operation fails.
59  *
60  * CREATION OF NODES
61  *
62  * The class interface supports creation of nodes by cloning a so-called
63  * exemplar. The idea is that it is sometimes useful to implement different
64  * element types by different classes, and to implement this by looking up
65  * exemplars.
66  * Imagine you have three element types A, B, and C, and three classes
67  * a, b, and c implementing the node interface (for example, by providing
68  * different extensions, see below). The XML parser can be configured to
69  * have a lookup table
70  *   { A --> a0,  B --> b0, C --> c0 }
71  * where a0, b0, c0 are exemplars of the classes a, b, and c, i.e. empty
72  * objects belonging to these classes. If the parser finds an instance of
73  * A, it looks up the exemplar a0 of A and clones it (actually, the method
74  * "create_element" performs this for elements, and "create_data" for data
75  * nodes). Clones belong to the same class as the original nodes, so the
76  * instances of the elements have the same classes as the configured
77  * exemplars.
78  * Note: This technique assumes that the interface of all exemplars is the
79  * same!
80  *
81  * THE EXTENSION
82  *
83  * The class type node and all its implementations have a class parameter
84  * 'ext which must at least fulfil the properties of the class type "extension".
85  * The idea is that you can add properties, for example:
86  *
87  * class my_extension =
88  *   object
89  *     (* minimal properties required by class type "extension": *)
90  *     method clone = ...
91  *     method node = ...
92  *     method set_node n = ...
93  *     (* here my own methods: *)
94  *     method do_this_and_that ...
95  *   end
96  *
97  * class my_element_impl = [ my_extension ] element_impl
98  * class my_data_impl    = [ my_extension ] data_impl
99  *
100  * The whole XML parser is parameterized with 'ext, so your extension is
101  * visible everywhere (this is the reason why extensibility is solved by
102  * parametric polymorphism and not by inclusive polymorphism (subtyping)).
103  *
104  *
105  * SOME COMPLICATED TYPE EXPRESSIONS
106  *
107  * Sometimes the following type expressions turn out to be necessary:
108  *
109  * 'a node extension as 'a
110  *      This is the type of an extension that belongs to a node that
111  *      has an extension that is the same as we started with.
112  *
113  * 'a extension node as 'a
114  *      This is the type of a node that has an extension that belongs to a
115  *      node of the type we started with.
116  *
117  *
118  * DOCUMENTS
119  * ...
120  *
121  * ======================================================================
122  *
123  * SIMPLE USAGE: ...
124  *)
125
126
127 open Markup_dtd
128
129
130 type node_type = 
131     T_element of string
132   | T_data
133
134
135
136 class type [ 'node ] extension =
137   object ('self)
138     method clone : 'self
139       (* "clone" should return an exact deep copy of the object. *)
140     method node : 'node
141       (* "node" returns the corresponding node of this extension. This method
142        * intended to return exactly what previously has been set by "set_node".
143        *)
144     method set_node : 'node -> unit
145       (* "set_node" is invoked once the extension is associated to a new
146        * node object.
147        *)
148   end
149 ;;
150
151 class type [ 'ext, 'node ] pxp_extension_type =
152 object ('self)
153     method clone : 'self
154     method node : 'self Pxp_document.node
155     method set_node : 'self Pxp_document.node -> unit
156
157     method markup_node : 'node
158     method set_markup_node : 'node -> unit
159
160     method set_index : 'self Pxp_yacc.index -> unit
161     method index : 'self Pxp_yacc.index
162   end
163 ;;
164
165 class type [ 'ext ] node =
166   object ('self)
167     constraint 'ext = 'ext node #extension
168     method pxp_node : (('ext, 'ext node) pxp_extension_type) Pxp_document.node
169
170     method extension : 'ext
171       (* Return the extension of this node: *)
172
173     method delete : unit
174       (* Delete this node from the parent's list of sub nodes. This node gets
175        * orphaned.
176        * 'delete' does nothing if this node does not have a parent.
177        *)
178
179     method parent : 'ext node
180       (* Get the parent, or raise Not_found if this node is an orphan. *)
181
182     method root : 'ext node
183       (* Get the direct or indirect parent that does not have a parent itself,
184        * i.e. the root of the tree.
185        *)
186
187     method orphaned_clone : 'ext node
188       (* return an exact clone of this element and all sub nodes (deep copy)
189        * except string values which are shared by this node and the clone.
190        * The other exception is that the clone has no parent (i.e. it is now
191        * a root).
192        *)
193
194     method orphaned_flat_clone : 'ext node
195       (* return a clone of this element where all subnodes are omitted.
196        * The type of the node, and the attributes are the same as in the
197        * original node.
198        * The clone has no parent.
199        *)
200
201     method add_node : 'ext node -> unit
202       (* Append new sub nodes -- mainly used by the parser itself, but
203        * of course open for everybody. If an element is added, it must be
204        * an orphan (i.e. does not have a parent node); and after addition
205        * *this* node is the new parent.
206        *)
207
208     method add_pinstr : proc_instruction -> unit
209       (* Add a processing instruction to the set of processing instructions of
210        * this node. Usually only elements contain processing instructions.
211        *)
212
213     method pinstr : string -> proc_instruction list
214       (* Get all processing instructions with the passed name *)
215
216     method pinstr_names : string list
217       (* Get a list of all names of processing instructions *)
218
219     method sub_nodes : 'ext node list
220       (* Get the list of sub nodes *)
221
222     method iter_nodes : ('ext node -> unit) -> unit
223       (* iterate over the sub nodes *)
224
225     method iter_nodes_sibl :
226       ('ext node option -> 'ext node -> 'ext node option -> unit) -> unit
227       (* Here every iteration step can also access to the previous and to the
228        * following node if present:
229        *)
230
231     method find : string -> 'ext node
232       (* Get the node that has an ID attribute with this value, or raise
233        * Not_found.
234        * "find" may also cause a Validation_error if something is wrong
235        * with the IDs.
236        *)
237
238     method reset_finder : unit
239       (* makes that newly added nodes will also be found *)
240
241     method set_nodes : 'ext node list -> unit
242       (* Set the list of sub nodes. Elements that are no longer sub nodes gets
243        * orphaned, and all new elements that previously were not sub nodes
244        * must have been orphaned.
245        *)
246
247     method data : string
248       (* Get the data string of this node. For data nodes, this string is just
249        * the content. For elements, this string is the concatenation of all
250        * subordinate data nodes.
251        *)
252
253     method node_type : node_type
254       (* Get the name of the element type. *)
255
256     method attribute : string -> Markup_types.att_value
257     method attribute_names : string list
258     method attribute_type : string -> Markup_types.att_type
259     method attributes : (string * Markup_types.att_value) list
260       (* Get a specific attribute; get the names of all attributes; get the
261        * type of a specific attribute; get names and values of all attributes.
262        * Only elements have attributes.
263        * Note: If the DTD allows arbitrary for this element, "attribute_type"
264        * raises Undeclared.
265        *)
266
267     method required_string_attribute : string -> string
268     method required_list_attribute : string -> string list
269       (* Return the attribute or fail if the attribute is not present:
270        * The first version passes the value always as string back;
271        * the second version always as list.
272        *)
273
274     method optional_string_attribute : string -> string option
275     method optional_list_attribute : string -> string list
276       (* Return some attribute value or return None if the attribute is not
277        *  present:
278        * The first version passes the value always as string back;
279        * the second version always as list.
280        *)
281
282     method quick_set_attributes : (string * Markup_types.att_value) list -> unit
283       (* Sets the attributes but does not check whether they match the DTD.
284        *)
285
286      method dtd : dtd
287        (* Get the DTD *)
288
289     method create_element : dtd -> node_type -> (string * string) list -> 'ext node
290       (* create an "empty copy" of this element:
291        * - new DTD
292        * - new node type
293        * - new attribute list
294        * - empty list of nodes
295        *)
296
297     method create_data : dtd -> string -> 'ext node
298       (* create an "empty copy" of this data node: *)
299
300     method local_validate : unit
301       (* Check that this element conforms to the DTD: *)
302
303     method keep_always_whitespace_mode : unit
304       (* Normally, add_node does not accept data nodes when the DTD does not
305        * allow data nodes or only whitespace ("ignorable whitespace").
306        * Once you have invoked this method, ignorable whitespace is forced
307        * to be included into the document.
308        *)
309
310     method write_compact_as_latin1 : Markup_types.output_stream -> unit
311       (* Write the contents of this node and the subtrees to the passed
312        * output stream; the character set ISO-8859-1 is used. The format
313        * is compact (the opposite of "pretty printing").
314        *)
315
316     (* ---------------------------------------- *)
317     (* internal methods: *)
318     method internal_adopt : 'ext node option -> unit
319     method internal_delete : 'ext node -> unit
320     method internal_init : dtd -> string -> (string * string) list -> unit
321   end
322 ;;
323
324 class [ 'ext ] data_impl : 'ext -> string -> [ 'ext ] node
325
326 class [ 'ext ] element_impl : 'ext -> [ 'ext ] node
327
328 class [ 'ext ] document :
329   Markup_types.collect_warnings -> 
330   object
331     method init_xml_version : string -> unit
332     method init_xml_standalone : bool -> unit
333     method init_root : 'ext node -> unit
334
335     method xml_version : string
336     method xml_standalone : bool
337     method dtd : dtd
338     method root : 'ext node
339
340     method add_pinstr : proc_instruction -> unit
341     method pinstr : string -> proc_instruction list
342     method pinstr_names : string list
343
344     method write_compact_as_latin1 : Markup_types.output_stream -> unit
345       (* Write the document to the passed
346        * output stream; the character set ISO-8859-1 is used. The format
347        * is compact (the opposite of "pretty printing").
348        * If a DTD is present, the DTD is included into the internal subset.
349        *)
350
351   end
352 ;;
353
354
355 (* ======================================================================
356  * History:
357  *
358  * $Log$
359  * Revision 1.1  2000/11/17 09:57:30  lpadovan
360  * Initial revision
361  *
362  * Revision 1.4  2000/08/18 20:19:16  gerd
363  *      Updates in the emulation because of PXP changes.
364  *
365  * Revision 1.3  2000/07/16 16:35:06  gerd
366  *      Update because PXP interface contains now the method 'write'.
367  *
368  * Revision 1.2  2000/06/14 22:19:27  gerd
369  *      Update because of additional 'encoding' methods.
370  *
371  * Revision 1.1  2000/05/29 23:43:51  gerd
372  *      Initial compatibility revision.
373  *
374  * ======================================================================
375  * OLD LOGS:
376  *
377  * Revision 1.13  2000/05/27 19:15:08  gerd
378  *      Removed the method init_xml_standalone.
379  *
380  * Revision 1.12  2000/05/01 20:42:34  gerd
381  *         New method write_compact_as_latin1.
382  *
383  * Revision 1.11  2000/04/30 18:15:57  gerd
384  *      Beautifications.
385  *      New method keep_always_whitespace_mode.
386  *
387  * Revision 1.10  2000/03/11 22:58:15  gerd
388  *      Updated to support Markup_codewriter.
389  *
390  * Revision 1.9  2000/01/27 21:51:56  gerd
391  *      Added method 'attributes'.
392  *
393  * Revision 1.8  2000/01/27 21:19:07  gerd
394  *      Added further methods.
395  *
396  * Revision 1.7  1999/11/09 22:20:14  gerd
397  *      Removed method init_dtd from class "document". The DTD is
398  * implicitly passed to the document by the root element.
399  *
400  * Revision 1.6  1999/09/01 22:51:40  gerd
401  *      Added methods to store processing instructions.
402  *
403  * Revision 1.5  1999/09/01 16:19:57  gerd
404  *      The "document" class has now a "warner" as class argument.
405  *
406  * Revision 1.4  1999/08/19 21:59:13  gerd
407  *      Added method "reset_finder".
408  *
409  * Revision 1.3  1999/08/19 01:08:29  gerd
410  *      Added method "find".
411  *
412  * Revision 1.2  1999/08/15 02:19:41  gerd
413  *      Some new explanations: That unknown elements are not rejected
414  * if the DTD allows them.
415  *
416  * Revision 1.1  1999/08/10 00:35:51  gerd
417  *      Initial revision.
418  *
419  *
420  *)