2 * ----------------------------------------------------------------------
3 * Markup! The validating XML parser for Objective Caml.
4 * Copyright 1999 by Gerd Stolpmann. See LICENSE for details.
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.
10 (**********************************************************************)
12 (* Markup_document: *)
13 (* Object model of the document/element instances *)
15 (**********************************************************************)
18 (* ======================================================================
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
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
34 * ======================================================================
36 * THE STRUCTURE OF NODE TREES:
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
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.
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
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
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
78 * Note: This technique assumes that the interface of all exemplars is the
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:
87 * class my_extension =
89 * (* minimal properties required by class type "extension": *)
92 * method set_node n = ...
93 * (* here my own methods: *)
94 * method do_this_and_that ...
97 * class my_element_impl = [ my_extension ] element_impl
98 * class my_data_impl = [ my_extension ] data_impl
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)).
105 * SOME COMPLICATED TYPE EXPRESSIONS
107 * Sometimes the following type expressions turn out to be necessary:
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.
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.
121 * ======================================================================
136 class type [ 'node ] extension =
139 (* "clone" should return an exact deep copy of the object. *)
141 (* "node" returns the corresponding node of this extension. This method
142 * intended to return exactly what previously has been set by "set_node".
144 method set_node : 'node -> unit
145 (* "set_node" is invoked once the extension is associated to a new
151 class type [ 'ext, 'node ] pxp_extension_type =
154 method node : 'self Pxp_document.node
155 method set_node : 'self Pxp_document.node -> unit
157 method markup_node : 'node
158 method set_markup_node : 'node -> unit
160 method set_index : 'self Pxp_yacc.index -> unit
161 method index : 'self Pxp_yacc.index
165 class type [ 'ext ] node =
167 constraint 'ext = 'ext node #extension
168 method pxp_node : (('ext, 'ext node) pxp_extension_type) Pxp_document.node
170 method extension : 'ext
171 (* Return the extension of this node: *)
174 (* Delete this node from the parent's list of sub nodes. This node gets
176 * 'delete' does nothing if this node does not have a parent.
179 method parent : 'ext node
180 (* Get the parent, or raise Not_found if this node is an orphan. *)
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.
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
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
198 * The clone has no parent.
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.
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.
213 method pinstr : string -> proc_instruction list
214 (* Get all processing instructions with the passed name *)
216 method pinstr_names : string list
217 (* Get a list of all names of processing instructions *)
219 method sub_nodes : 'ext node list
220 (* Get the list of sub nodes *)
222 method iter_nodes : ('ext node -> unit) -> unit
223 (* iterate over the sub nodes *)
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:
231 method find : string -> 'ext node
232 (* Get the node that has an ID attribute with this value, or raise
234 * "find" may also cause a Validation_error if something is wrong
238 method reset_finder : unit
239 (* makes that newly added nodes will also be found *)
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.
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.
253 method node_type : node_type
254 (* Get the name of the element type. *)
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"
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.
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
278 * The first version passes the value always as string back;
279 * the second version always as list.
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.
289 method create_element : dtd -> node_type -> (string * string) list -> 'ext node
290 (* create an "empty copy" of this element:
293 * - new attribute list
294 * - empty list of nodes
297 method create_data : dtd -> string -> 'ext node
298 (* create an "empty copy" of this data node: *)
300 method local_validate : unit
301 (* Check that this element conforms to the DTD: *)
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.
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").
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
324 class [ 'ext ] data_impl : 'ext -> string -> [ 'ext ] node
326 class [ 'ext ] element_impl : 'ext -> [ 'ext ] node
328 class [ 'ext ] document :
329 Markup_types.collect_warnings ->
331 method init_xml_version : string -> unit
332 method init_xml_standalone : bool -> unit
333 method init_root : 'ext node -> unit
335 method xml_version : string
336 method xml_standalone : bool
338 method root : 'ext node
340 method add_pinstr : proc_instruction -> unit
341 method pinstr : string -> proc_instruction list
342 method pinstr_names : string list
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.
355 (* ======================================================================
359 * Revision 1.1 2000/11/17 09:57:30 lpadovan
362 * Revision 1.4 2000/08/18 20:19:16 gerd
363 * Updates in the emulation because of PXP changes.
365 * Revision 1.3 2000/07/16 16:35:06 gerd
366 * Update because PXP interface contains now the method 'write'.
368 * Revision 1.2 2000/06/14 22:19:27 gerd
369 * Update because of additional 'encoding' methods.
371 * Revision 1.1 2000/05/29 23:43:51 gerd
372 * Initial compatibility revision.
374 * ======================================================================
377 * Revision 1.13 2000/05/27 19:15:08 gerd
378 * Removed the method init_xml_standalone.
380 * Revision 1.12 2000/05/01 20:42:34 gerd
381 * New method write_compact_as_latin1.
383 * Revision 1.11 2000/04/30 18:15:57 gerd
385 * New method keep_always_whitespace_mode.
387 * Revision 1.10 2000/03/11 22:58:15 gerd
388 * Updated to support Markup_codewriter.
390 * Revision 1.9 2000/01/27 21:51:56 gerd
391 * Added method 'attributes'.
393 * Revision 1.8 2000/01/27 21:19:07 gerd
394 * Added further methods.
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.
400 * Revision 1.6 1999/09/01 22:51:40 gerd
401 * Added methods to store processing instructions.
403 * Revision 1.5 1999/09/01 16:19:57 gerd
404 * The "document" class has now a "warner" as class argument.
406 * Revision 1.4 1999/08/19 21:59:13 gerd
407 * Added method "reset_finder".
409 * Revision 1.3 1999/08/19 01:08:29 gerd
410 * Added method "find".
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.
416 * Revision 1.1 1999/08/10 00:35:51 gerd