4 >The class type node</TITLE
7 CONTENT="Modular DocBook HTML Stylesheet Version 1.46"><LINK
9 TITLE="The PXP user's guide"
10 HREF="index.html"><LINK
12 TITLE="The objects representing the document"
13 HREF="c893.html"><LINK
15 TITLE="The objects representing the document"
16 HREF="c893.html"><LINK
18 TITLE="The class type extension"
19 HREF="x1439.html"><LINK
22 HREF="markup.css"></HEAD
41 >The PXP user's guide</TH
56 >Chapter 3. The objects representing the document</TD
76 >3.2. The class type <TT
88 CLASS="PROGRAMLISTING"
98 >and some other, reserved types</I
103 class type [ 'ext ] node =
105 constraint 'ext = 'ext node #extension
108 NAME="TYPE-NODE-GENERAL.SIG"
111 HREF="x939.html#TYPE-NODE-GENERAL"
114 >General observers</I
119 method extension : 'ext
121 method parent : 'ext node
122 method root : 'ext node
123 method sub_nodes : 'ext node list
124 method iter_nodes : ('ext node -> unit) -> unit
125 method iter_nodes_sibl :
126 ('ext node option -> 'ext node -> 'ext node option -> unit) -> unit
127 method node_type : node_type
128 method encoding : Pxp_types.rep_encoding
130 method position : (string * int * int)
131 method comment : string option
132 method pinstr : string -> proc_instruction list
133 method pinstr_names : string list
134 method write : Pxp_types.output_stream -> Pxp_types.encoding -> unit
137 NAME="TYPE-NODE-ATTS.SIG"
140 HREF="x939.html#TYPE-NODE-ATTS"
143 >Attribute observers</I
148 method attribute : string -> Pxp_types.att_value
149 method required_string_attribute : string -> string
150 method optional_string_attribute : string -> string option
151 method required_list_attribute : string -> string list
152 method optional_list_attribute : string -> string list
153 method attribute_names : string list
154 method attribute_type : string -> Pxp_types.att_type
155 method attributes : (string * Pxp_types.att_value) list
156 method id_attribute_name : string
157 method id_attribute_value : string
158 method idref_attribute_names : string
161 NAME="TYPE-NODE-MODS.SIG"
164 HREF="x939.html#TYPE-NODE-MODS"
167 >Modifying methods</I
172 method add_node : ?force:bool -> 'ext node -> unit
173 method add_pinstr : proc_instruction -> unit
175 method set_nodes : 'ext node list -> unit
176 method quick_set_attributes : (string * Pxp_types.att_value) list -> unit
177 method set_comment : string option -> unit
180 NAME="TYPE-NODE-CLONING.SIG"
183 HREF="x939.html#TYPE-NODE-CLONING"
191 method orphaned_clone : 'self
192 method orphaned_flat_clone : 'self
193 method create_element :
194 ?position:(string * int * int) ->
195 dtd -> node_type -> (string * string) list ->
197 method create_data : dtd -> string -> 'ext node
198 method keep_always_whitespace_mode : unit
201 NAME="TYPE-NODE-WEIRD.SIG"
204 HREF="x939.html#TYPE-NODE-WEIRD"
207 >Validating methods</I
212 method local_validate : ?use_dfa:bool -> unit -> unit
214 (* ... Internal methods are undocumented. *)
223 > you can find another type
224 definition that is important in this context:
227 CLASS="PROGRAMLISTING"
228 >type Pxp_types.att_value =
230 | Valuelist of string list
240 >3.2.1. The structure of document trees</A
243 >A node represents either an element or a character data section. There are two
244 classes implementing the two aspects of nodes: <TT
251 >. The latter class does not implement all
252 methods because some methods do not make sense for data nodes.</P
254 >(Note: PXP also supports a mode which forces that processing instructions and
255 comments are represented as nodes of the document tree. However, these nodes
267 respectively. This mode must be explicitly configured; the basic representation
268 knows only element and data nodes.)</P
270 >The following figure
272 HREF="x939.html#NODE-TERM"
275 >A tree with element nodes, data nodes, and attributes</I
280 >) shows an example how
281 a tree is constructed from element and data nodes. The circular areas
282 represent element nodes whereas the ovals denote data nodes. Only elements
283 may have subnodes; data nodes are always leaves of the tree. The subnodes
284 of an element can be either element or data nodes; in both cases the O'Caml
285 objects storing the nodes have the class type <TT
290 >Attributes (the clouds in the picture) are not directly
291 integrated into the tree; there is always an extra link to the attribute
292 list. This is also true for processing instructions (not shown in the
293 picture). This means that there are separated access methods for attributes and
294 processing instructions.</P
302 >Figure 3-1. A tree with element nodes, data nodes, and attributes</B
306 SRC="pic/node_term.gif"></P
309 >Only elements, data sections, attributes and processing
310 instructions (and comments, if configured) can, directly or indirectly, occur
311 in the document tree. It is impossible to add entity references to the tree; if
312 the parser finds such a reference, not the reference as such but the referenced
313 text (i.e. the tree representing the structured text) is included in the
316 >Note that the parser collapses as much data material into one
317 data node as possible such that there are normally never two adjacent data
318 nodes. This invariant is enforced even if data material is included by entity
319 references or CDATA sections, or if a data sequence is interrupted by
322 >a &amp; b <-- comment --> c <![CDATA[
324 > is represented by only one data node, for
325 instance. However, you can create document trees manually which break this
326 invariant; it is only the way the parser forms the tree.</P
334 >Figure 3-2. Nodes are doubly linked trees</B
338 SRC="pic/node_general.gif"></P
341 >The node tree has links in both directions: Every node has a link to its parent
342 (if any), and it has links to the subnodes (see
344 HREF="x939.html#NODE-GENERAL"
347 >Nodes are doubly linked trees</I
353 this doubly-linked structure simplifies the navigation in the tree; but has
354 also some consequences for the possible operations on trees.</P
356 >Because every node must have at most <I
360 operations are illegal if they violate this condition. The following figure
362 HREF="x939.html#NODE-ADD"
365 >A node can only be added if it is a root</I
370 >) shows on the left side
378 which is allowed because <TT
381 > does not have a parent yet. The
382 right side of the picture illustrates what would happen if <TT
386 had a parent node; this is illegal because <TT
390 parents after the operation.</P
398 >Figure 3-3. A node can only be added if it is a root</B
402 SRC="pic/node_add.gif"></P
405 >The "delete" operation simply removes the links between two nodes. In the
407 HREF="x939.html#NODE-DELETE"
410 >A deleted node becomes the root of the subtree</I
419 > is deleted from the list of subnodes of
426 > becomes the root of the
427 subtree starting at this node.</P
435 >Figure 3-4. A deleted node becomes the root of the subtree</B
439 SRC="pic/node_delete.gif"></P
442 >It is also possible to make a clone of a subtree; illustrated in
444 HREF="x939.html#NODE-CLONE"
447 >The clone of a subtree</I
453 clone is a copy of the original subtree except that it is no longer a
454 subnode. Because cloning never keeps the connection to the parent, the clones
466 >Figure 3-5. The clone of a subtree</B
470 SRC="pic/node_clone.gif"></P
479 >3.2.2. The methods of the class type <TT
485 NAME="TYPE-NODE-GENERAL"
492 HREF="x939.html#TYPE-NODE-GENERAL.SIG"
493 >General observers</A
501 STYLE="list-style-type: disc"
506 >: The reference to the extension object which
507 belongs to this node (see ...).</P
510 STYLE="list-style-type: disc"
515 >: Returns a reference to the global DTD. All nodes
516 of a tree must share the same DTD.</P
519 STYLE="list-style-type: disc"
524 >: Get the father node. Raises
528 > in the case the node does not have a
529 parent, i.e. the node is the root.</P
532 STYLE="list-style-type: disc"
537 >: Gets the reference to the root node of the tree.
538 Every node is contained in a tree with a root, so this method always
539 succeeds. Note that this method <I
543 which costs time proportional to the length of the path to the root.</P
546 STYLE="list-style-type: disc"
551 >: Returns references to the children. The returned
552 list reflects the order of the children. For data nodes, this method returns
556 STYLE="list-style-type: disc"
561 >: Iterates over the children, and calls
565 > for every child in turn. </P
568 STYLE="list-style-type: disc"
572 >iter_nodes_sibl f</TT
573 >: Iterates over the children, and calls
577 > for every child in turn. <TT
581 arguments the previous node, the current node, and the next node.</P
584 STYLE="list-style-type: disc"
589 >: Returns either <TT
593 means that the node is a data node, or <TT
597 which means that the node is an element of type <TT
601 If configured, possible node types are also <TT
605 indicating that the node represents a processing instruction with target
612 > in which case the node
616 STYLE="list-style-type: disc"
621 >: Returns the encoding of the strings.</P
624 STYLE="list-style-type: disc"
629 >: Returns the character data of this node and all
630 children, concatenated as one string. The encoding of the string is what
635 - For data nodes, this method simply returns the represented characters.
636 For elements, the meaning of the method has been extended such that it
637 returns something useful, i.e. the effectively contained characters, without
645 nodes, the method returns the empty string.)</P
648 STYLE="list-style-type: disc"
653 >: If configured, this method returns the position of
654 the element as triple (entity, line, byteposition). For data nodes, the
655 position is not stored. If the position is not available the triple
662 STYLE="list-style-type: disc"
674 > for other nodes. The <TT
678 is everything between the comment delimiters <TT
688 STYLE="list-style-type: disc"
693 >: Returns all processing instructions that are
694 directly contained in this element and that have a <I
701 >. The target is the first word after
708 STYLE="list-style-type: disc"
713 >: Returns the list of all targets of processing
714 instructions directly contained in this element.</P
717 STYLE="list-style-type: disc"
722 >: Prints the node and all subnodes to the passed
723 output stream as valid XML text, using the passed external encoding.</P
730 NAME="TYPE-NODE-ATTS"
737 HREF="x939.html#TYPE-NODE-ATTS.SIG"
738 >Attribute observers</A
746 STYLE="list-style-type: disc"
751 >: Returns the value of the attribute with name
755 >. This method returns a value for every declared
756 attribute, and it raises <TT
760 attribute. Note that it even returns a value if the attribute is actually
761 missing but is declared as <TT
765 value. - Possible values are:
771 STYLE="list-style-type: disc"
776 >: The attribute has been declared with the
780 >, and the attribute is missing in the
781 attribute list of this element.</P
784 STYLE="list-style-type: disc"
789 >: The attribute has been declared as type
807 >, or as enumeration or notation, and one of the two
808 conditions holds: (1) The attribute value is present in the attribute list in
809 which case the value is returned in the string <TT
813 attribute has been omitted, and the DTD declared the attribute with a default
814 value. The default value is returned in <TT
821 > is returned for non-implied, non-list
825 STYLE="list-style-type: disc"
830 >: The attribute has been declared as type
841 >, and one of the two conditions holds: (1) The
842 attribute value is present in the attribute list in which case the
843 space-separated tokens of the value are returned in the string list
847 >. (2) The attribute has been omitted, and the DTD declared
848 the attribute with a default value. The default value is returned in
856 > is returned for all list-type
862 Note that before the attribute value is returned, the value is normalized. This
863 means that newlines are converted to spaces, and that references to character
883 if necessary, expansion is performed recursively.</P
885 >In well-formedness mode, there is no DTD which could declare an
886 attribute. Because of this, every occuring attribute is considered as a CDATA
890 STYLE="list-style-type: disc"
894 >required_string_attribute n</TT
895 >: returns the Value attribute
896 called n, or the Valuelist attribute as a string where the list elements
897 are separated by spaces. If the attribute value is implied, or if the
898 attribute does not exists, the method will fail. - This method is convenient
899 if you expect a non-implied and non-list attribute value.</P
902 STYLE="list-style-type: disc"
906 >optional_string_attribute n</TT
907 >: returns the Value attribute
908 called n, or the Valuelist attribute as a string where the list elements
909 are separated by spaces. If the attribute value is implied, or if the
910 attribute does not exists, the method returns None. - This method is
911 convenient if you expect a non-list attribute value including the implied
915 STYLE="list-style-type: disc"
919 >required_list_attribute n</TT
920 >: returns the Valuelist attribute
921 called n, or the Value attribute as a list with a single element.
922 If the attribute value is implied, or if the
923 attribute does not exists, the method will fail. - This method is
924 convenient if you expect a list attribute value.</P
927 STYLE="list-style-type: disc"
931 >optional_list_attribute n</TT
932 >: returns the Valuelist attribute
933 called n, or the Value attribute as a list with a single element.
934 If the attribute value is implied, or if the
935 attribute does not exists, an empty list will be returned. - This method
936 is convenient if you expect a list attribute value or the implied value.</P
939 STYLE="list-style-type: disc"
944 >: returns the list of all attribute names of
945 this element. As this is a validating parser, this list is equal to the
946 list of declared attributes.</P
949 STYLE="list-style-type: disc"
953 >attribute_type n</TT
954 >: returns the type of the attribute called
958 >. See the module <TT
962 description of the encoding of the types.</P
965 STYLE="list-style-type: disc"
970 >: returns the list of pairs of names and values
971 for all attributes of
975 STYLE="list-style-type: disc"
979 >id_attribute_name</TT
980 >: returns the name of the attribute that is
981 declared with type ID. There is at most one such attribute. The method raises
985 > if there is no declared ID attribute for the
989 STYLE="list-style-type: disc"
993 >id_attribute_value</TT
994 >: returns the value of the attribute that
995 is declared with type ID. There is at most one such attribute. The method raises
999 > if there is no declared ID attribute for the
1003 STYLE="list-style-type: disc"
1007 >idref_attribute_names</TT
1008 >: returns the list of attribute names
1009 that are declared as IDREF or IDREFS.</P
1016 NAME="TYPE-NODE-MODS"
1023 HREF="x939.html#TYPE-NODE-MODS.SIG"
1024 >Modifying methods</A
1027 >The following methods are only defined for element nodes (more exactly:
1028 the methods are defined for data nodes, too, but fail always).
1035 STYLE="list-style-type: disc"
1040 >: Adds sub node <TT
1044 of children. This operation is illustrated in the picture
1046 HREF="x939.html#NODE-ADD"
1049 >A node can only be added if it is a root</I
1054 >. This method expects that
1058 > is a root, and it requires that <TT
1062 the current object share the same DTD.</P
1067 > is the method the parser itself uses
1068 to add new nodes to the tree, it performs by default some simple validation
1069 checks: If the content model is a regular expression, it is not allowed to add
1070 data nodes to this node unless the new nodes consist only of whitespace. In
1071 this case, the new data nodes are silently dropped (you can change this by
1074 >keep_always_whitespace_mode</TT
1077 >If the document is flagged as stand-alone, these data nodes only
1078 containing whitespace are even forbidden if the element declaration is
1079 contained in an external entity. This case is detected and rejected.</P
1081 >If the content model is <TT
1084 >, it is not allowed to
1085 add any data node unless the data node is empty. In this case, the new data
1086 node is silently dropped.</P
1088 >These checks only apply if there is a DTD. In well-formedness mode, it is
1089 assumed that every element is declared with content model
1093 > which prohibits any validation check. Furthermore, you
1094 turn these checks off by passing <TT
1101 STYLE="list-style-type: disc"
1106 >: Adds the processing instruction
1110 > to the list of processing instructions.</P
1113 STYLE="list-style-type: disc"
1118 >: Deletes this node from the tree. After this
1119 operation, this node is no longer the child of the former father node; and the
1120 node loses the connection to the father as well. This operation is illustrated
1122 HREF="x939.html#NODE-DELETE"
1125 >A deleted node becomes the root of the subtree</I
1133 STYLE="list-style-type: disc"
1138 >: Sets the list of children to
1142 >. It is required that every member of <TT
1146 is a root, and that all members and the current object share the same DTD.
1150 >, no validation checks are performed.</P
1153 STYLE="list-style-type: disc"
1157 >quick_set_attributes atts</TT
1158 >: sets the attributes of this
1169 > matches the DTD or not; it is up to the
1170 caller of this method to ensure this. (This method may be useful to transform
1171 the attribute values, i.e. apply a mapping to every attribute.)</P
1174 STYLE="list-style-type: disc"
1178 >set_comment text</TT
1179 >: This method is only applicable to
1183 > nodes; it sets the comment text contained by such
1190 NAME="TYPE-NODE-CLONING"
1197 HREF="x939.html#TYPE-NODE-CLONING.SIG"
1206 STYLE="list-style-type: disc"
1211 >: Returns a clone of the node and the complete
1212 tree below this node (deep clone). The clone does not have a parent (i.e. the
1213 reference to the parent node is <I
1217 copying the subtree, strings are skipped; it is likely that the original tree
1218 and the copy tree share strings. Extension objects are cloned by invoking
1222 > method on the original objects; how much of
1223 the extension objects is cloned depends on the implemention of this method.</P
1225 >This operation is illustrated by the figure
1227 HREF="x939.html#NODE-CLONE"
1230 >The clone of a subtree</I
1238 STYLE="list-style-type: disc"
1242 >orphaned_flat_clone</TT
1243 >: Returns a clone of the node,
1244 but sets the list of sub nodes to [], i.e. the sub nodes are not cloned.</P
1247 STYLE="list-style-type: disc"
1250 NAME="TYPE-NODE-METH-CREATE-ELEMENT"
1255 >create_element dtd nt al</TT
1256 >: Returns a flat copy of this node
1257 (which must be an element) with the following modifications: The DTD is set to
1261 >; the node type is set to <TT
1265 new attribute list is set to <TT
1269 (name,value) pairs). The copy does not have children nor a parent. It does not
1270 contain processing instructions. See
1272 HREF="x939.html#TYPE-NODE-EX-CREATE-ELEMENT"
1273 >the example below</A
1276 >Note that you can specify the position of the new node
1277 by the optional argument <TT
1283 STYLE="list-style-type: disc"
1286 NAME="TYPE-NODE-METH-CREATE-DATA"
1291 >create_data dtd cdata</TT
1292 >: Returns a flat copy of this node
1293 (which must be a data node) with the following modifications: The DTD is set to
1297 >; the node type is set to <TT
1301 attribute list is empty (data nodes never have attributes); the list of
1302 children and PIs is empty, too (same reason). The new node does not have a
1303 parent. The value <TT
1306 > is the new character content of the
1309 HREF="x939.html#TYPE-NODE-EX-CREATE-DATA"
1310 >the example below</A
1314 STYLE="list-style-type: disc"
1318 >keep_always_whitespace_mode</TT
1319 >: Even data nodes which are
1320 normally dropped because they only contain ignorable whitespace, can added to
1321 this node once this mode is turned on. (This mode is useful to produce
1328 NAME="TYPE-NODE-WEIRD"
1335 HREF="x939.html#TYPE-NODE-WEIRD.SIG"
1336 >Validating methods</A
1339 >There is one method which locally validates the node, i.e. checks whether the
1340 subnodes match the content model of this node.
1347 STYLE="list-style-type: disc"
1352 >: Checks that this node conforms to the
1353 DTD by comparing the type of the subnodes with the content model for this
1354 node. (Applications need not call this method unless they add new nodes
1355 themselves to the tree.)</P
1367 >3.2.3. The class <TT
1373 >This class is an implementation of <TT
1377 realizes element nodes:
1380 CLASS="PROGRAMLISTING"
1381 >class [ 'ext ] element_impl : 'ext -> [ 'ext ] node</PRE
1388 >You can create a new instance by
1391 CLASS="PROGRAMLISTING"
1392 >new element_impl <TT
1395 >extension_object</I
1400 which creates a special form of empty element which already contains a
1401 reference to the <TT
1404 >extension_object</I
1407 otherwise empty. This special form is called an
1411 >. The purpose of exemplars is that they serve as
1412 patterns that can be duplicated and filled with data. The method
1414 HREF="x939.html#TYPE-NODE-METH-CREATE-ELEMENT"
1419 > is designed to perform this action.</P
1422 NAME="TYPE-NODE-EX-CREATE-ELEMENT"
1429 >First, create an exemplar by
1432 CLASS="PROGRAMLISTING"
1433 >let exemplar_ext = ... in
1434 let exemplar = new element_impl exemplar_ext in</PRE
1440 > is not used in node trees, but only as
1441 a pattern when the element nodes are created:
1444 CLASS="PROGRAMLISTING"
1445 >let element = exemplar # <A
1446 HREF="x939.html#TYPE-NODE-METH-CREATE-ELEMENT"
1448 > dtd (T_element name) attlist </PRE
1458 (even the extension <TT
1462 which ensures that <TT
1465 > and its extension are objects
1466 of the same class as the exemplars; note that you need not to pass a
1467 class name or other meta information. The copy is initially connected
1471 >, it gets a node type, and the attribute list
1475 > is now fully functional; it can
1476 be added to another element as child, and it can contain references to
1486 >3.2.4. The class <TT
1492 >This class is an implementation of <TT
1496 should be used for all character data nodes:
1499 CLASS="PROGRAMLISTING"
1500 >class [ 'ext ] data_impl : 'ext -> [ 'ext ] node</PRE
1507 >You can create a new instance by
1510 CLASS="PROGRAMLISTING"
1514 >extension_object</I
1519 which creates an empty exemplar node which is connected to
1523 >extension_object</I
1525 >. The node does not contain a
1526 reference to any DTD, and because of this it cannot be added to node trees.</P
1529 >To get a fully working data node, apply the method
1531 HREF="x939.html#TYPE-NODE-METH-CREATE-DATA"
1536 > to the exemplar (see example).</P
1538 NAME="TYPE-NODE-EX-CREATE-DATA"
1545 >First, create an exemplar by
1548 CLASS="PROGRAMLISTING"
1549 >let exemplar_ext = ... in
1550 let exemplar = new exemplar_ext data_impl in</PRE
1556 > is not used in node trees, but only as
1557 a pattern when the data nodes are created:
1560 CLASS="PROGRAMLISTING"
1561 >let data_node = exemplar # <A
1562 HREF="x939.html#TYPE-NODE-METH-CREATE-DATA"
1564 > dtd "The characters contained in the data node" </PRE
1574 The copy is initially connected
1578 >, and it is filled with character material.
1582 > is now fully functional; it can
1583 be added to an element as child.</P
1592 >3.2.5. The type <TT
1601 > defines a way to handle the details of
1602 creating nodes from exemplars.
1605 CLASS="PROGRAMLISTING"
1607 constraint 'ext = 'ext node #extension
1609 val make_spec_from_mapping :
1610 ?super_root_exemplar : 'ext node ->
1611 ?comment_exemplar : 'ext node ->
1612 ?default_pinstr_exemplar : 'ext node ->
1613 ?pinstr_mapping : (string, 'ext node) Hashtbl.t ->
1614 data_exemplar: 'ext node ->
1615 default_element_exemplar: 'ext node ->
1616 element_mapping: (string, 'ext node) Hashtbl.t ->
1620 val make_spec_from_alist :
1621 ?super_root_exemplar : 'ext node ->
1622 ?comment_exemplar : 'ext node ->
1623 ?default_pinstr_exemplar : 'ext node ->
1624 ?pinstr_alist : (string * 'ext node) list ->
1625 data_exemplar: 'ext node ->
1626 default_element_exemplar: 'ext node ->
1627 element_alist: (string * 'ext node) list ->
1632 The two functions <TT
1634 >make_spec_from_mapping</TT
1638 >make_spec_from_alist</TT
1643 values. Both functions are functionally equivalent and the only difference is
1644 that the first function prefers hashtables and the latter associative lists to
1645 describe mappings from names to exemplars.</P
1647 >You can specify exemplars for the various kinds of nodes that need to be
1648 generated when an XML document is parsed:
1655 STYLE="list-style-type: disc"
1659 >~super_root_exemplar</TT
1661 is used to create the super root. This special node is only created if the
1662 corresponding configuration option has been selected; it is the parent node of
1663 the root node which may be convenient if every working node must have a parent.</P
1666 STYLE="list-style-type: disc"
1670 >~comment_exemplar</TT
1672 used when a comment node must be created. Note that such nodes are only created
1673 if the corresponding configuration option is "on".</P
1676 STYLE="list-style-type: disc"
1680 >~default_pinstr_exemplar</TT
1682 for a processing instruction must be created, and the instruction is not listed
1683 in the table passed by <TT
1685 >~pinstr_mapping</TT
1690 >, this exemplar is used.
1691 Again the configuration option must be "on" in order to create such nodes at
1695 STYLE="list-style-type: disc"
1699 >~pinstr_mapping</TT
1704 >: Map the target names of processing
1705 instructions to exemplars. These mappings are only used when nodes for
1706 processing instructions are created.</P
1709 STYLE="list-style-type: disc"
1715 ordinary data nodes.</P
1718 STYLE="list-style-type: disc"
1722 >~default_element_exemplar</TT
1724 exemplar is used if an element node must be created, but the element type
1725 cannot be found in the tables <TT
1727 >element_mapping</TT
1735 STYLE="list-style-type: disc"
1739 >~element_mapping</TT
1744 >: Map the element types to exemplars. These
1745 mappings are used to create element nodes.</P
1750 In most cases, you only want to create <TT
1754 them to the parser functions found in <TT
1758 might be useful to apply <TT
1761 > values directly.</P
1763 >The following functions create various types of nodes by selecting the
1764 corresponding exemplar from the passed <TT
1778 CLASS="PROGRAMLISTING"
1779 >val create_data_node :
1782 (* data material: *) string ->
1785 val create_element_node :
1786 ?position:(string * int * int) ->
1789 (* element type: *) string ->
1790 (* attributes: *) (string * string) list ->
1793 val create_super_root_node :
1794 ?position:(string * int * int) ->
1799 val create_comment_node :
1800 ?position:(string * int * int) ->
1803 (* comment text: *) string ->
1806 val create_pinstr_node :
1807 ?position:(string * int * int) ->
1810 proc_instruction ->
1826 >Building trees. </B
1827 >Here is the piece of code that creates the tree of
1829 HREF="x939.html#NODE-TERM"
1832 >A tree with element nodes, data nodes, and attributes</I
1838 object and the DTD are beyond the scope of this example.
1841 CLASS="PROGRAMLISTING"
1842 >let exemplar_ext = ... (* some extension *) in
1843 let dtd = ... (* some DTD *) in
1845 let element_exemplar = new element_impl exemplar_ext in
1846 let data_exemplar = new data_impl exemplar_ext in
1848 let a1 = element_exemplar # create_element dtd (T_element "a") ["att", "apple"]
1849 and b1 = element_exemplar # create_element dtd (T_element "b") []
1850 and c1 = element_exemplar # create_element dtd (T_element "c") []
1851 and a2 = element_exemplar # create_element dtd (T_element "a") ["att", "orange"]
1854 let cherries = data_exemplar # create_data dtd "Cherries" in
1855 let orange = data_exemplar # create_data dtd "An orange" in
1860 b1 # add_node cherries;
1861 a2 # add_node orange;</PRE
1864 Alternatively, the last block of statements could also be written as:
1867 CLASS="PROGRAMLISTING"
1868 >a1 # set_nodes [b1; c1];
1869 b1 # set_nodes [a2; cherries];
1870 a2 # set_nodes [orange];</PRE
1873 The root of the tree is <TT
1876 >, i.e. it is true that
1879 CLASS="PROGRAMLISTING"
1880 >x # root == a1</PRE
1883 for every x from { <TT
1906 >Furthermore, the following properties hold:
1909 CLASS="PROGRAMLISTING"
1910 > a1 # attribute "att" = Value "apple"
1911 & a2 # attribute "att" = Value "orange"
1913 & cherries # data = "Cherries"
1914 & orange # data = "An orange"
1915 & a1 # data = "CherriesAn orange"
1917 & a1 # node_type = T_element "a"
1918 & a2 # node_type = T_element "a"
1919 & b1 # node_type = T_element "b"
1920 & c1 # node_type = T_element "c"
1921 & cherries # node_type = T_data
1922 & orange # node_type = T_data
1924 & a1 # sub_nodes = [ b1; c1 ]
1925 & a2 # sub_nodes = [ orange ]
1926 & b1 # sub_nodes = [ a2; cherries ]
1927 & c1 # sub_nodes = []
1928 & cherries # sub_nodes = []
1929 & orange # sub_nodes = []
1931 & a2 # parent == a1
1932 & b1 # parent == b1
1933 & c1 # parent == a1
1934 & cherries # parent == b1
1935 & orange # parent == a2</PRE
1941 >Searching nodes. </B
1942 >The following function searches all nodes of a tree
1943 for which a certain condition holds:
1946 CLASS="PROGRAMLISTING"
1947 >let rec search p t =
1949 t :: search_list p (t # sub_nodes)
1951 search_list p (t # sub_nodes)
1953 and search_list p l =
1956 | t :: l' -> (search p t) @ (search_list p l')
1961 >For example, if you want to search all elements of a certain
1972 CLASS="PROGRAMLISTING"
1973 >let search_element_type et t =
1974 search (fun x -> x # node_type = T_element et) t
1981 >Getting attribute values. </B
1982 >Suppose we have the declaration:
1985 CLASS="PROGRAMLISTING"
1986 ><!ATTLIST e a CDATA #REQUIRED
1988 c CDATA "12345"></PRE
1991 In this case, every element <TT
1994 > must have an attribute
1998 >, otherwise the parser would indicate an error. If
1999 the O'Caml variable <TT
2002 > holds the node of the tree
2003 corresponding to the element, you can get the value of the attribute
2010 CLASS="PROGRAMLISTING"
2011 >let value_of_a = n # required_string_attribute "a"</PRE
2014 which is more or less an abbreviation for
2017 CLASS="PROGRAMLISTING"
2019 match n # attribute "a" with
2021 | _ -> assert false</PRE
2024 - as the attribute is required, the <TT
2034 >In contrast to this, the attribute <TT
2038 omitted. In this case, the method <TT
2040 >required_string_attribute</TT
2042 works only if the attribute is there, and the method will fail if the attribute
2043 is missing. To get the value, you can apply the method
2046 >optional_string_attribute</TT
2050 CLASS="PROGRAMLISTING"
2051 >let value_of_b = n # optional_string_attribute "b"</PRE
2064 > represents the omitted attribute. Alternatively,
2065 you could also use <TT
2071 CLASS="PROGRAMLISTING"
2073 match n # attribute "b" with
2074 Value s -> Some s
2075 | Implied_value -> None
2076 | _ -> assert false</PRE
2086 >, because it has always a value. If the attribute is
2087 omitted, the default, here "12345", will be returned instead. Because of this,
2088 you can again use <TT
2090 >required_string_attribute</TT
2097 > is the most general string
2111 >, and all enumerators and
2112 notations are special forms of string types that restrict the possible
2113 values. From O'Caml, they behave like <TT
2119 >required_string_attribute</TT
2123 >optional_string_attribute</TT
2126 >In contrast to this, the types <TT
2137 strings. Suppose we have the declaration:
2140 CLASS="PROGRAMLISTING"
2141 ><!ATTLIST f d NMTOKENS #REQUIRED
2142 e NMTOKENS #IMPLIED></PRE
2148 > stands for lists of space-separated
2149 tokens; for example the value <TT
2155 >["1"; "abc"; "23ef"]</TT
2163 > have more restricted values.) To get the
2164 value of attribute <TT
2170 CLASS="PROGRAMLISTING"
2171 >let value_of_d = n # required_list_attribute "d"</PRE
2177 CLASS="PROGRAMLISTING"
2179 match n # attribute "d" with
2180 Valuelist l -> l
2181 | _ -> assert false</PRE
2187 > is required, the attribute cannot be omitted, and
2191 > method returns always a
2197 >For optional attributes like <TT
2203 CLASS="PROGRAMLISTING"
2204 >let value_of_e = n # optional_list_attribute "e"</PRE
2210 CLASS="PROGRAMLISTING"
2212 match n # attribute "e" with
2213 Valuelist l -> l
2214 | Implied_value -> []
2215 | _ -> assert false</PRE
2218 Here, the case that the attribute is missing counts like the empty list.</P
2226 >3.2.7. Iterators</A
2229 >There are also several iterators in Pxp_document; please see
2230 the mli file for details. You can find examples for them in the
2231 "simple_transformation" directory.
2234 CLASS="PROGRAMLISTING"
2235 >val find : ?deeply:bool ->
2236 f:('ext node -> bool) -> 'ext node -> 'ext node
2238 val find_all : ?deeply:bool ->
2239 f:('ext node -> bool) -> 'ext node -> 'ext node list
2241 val find_element : ?deeply:bool ->
2242 string -> 'ext node -> 'ext node
2244 val find_all_elements : ?deeply:bool ->
2245 string -> 'ext node -> 'ext node list
2248 val map_tree : pre:('exta node -> 'extb node) ->
2249 ?post:('extb node -> 'extb node) ->
2255 pre: ('exta node option -> 'exta node -> 'exta node option ->
2257 ?post:('extb node option -> 'extb node -> 'extb node option ->
2262 val iter_tree : ?pre:('ext node -> unit) ->
2263 ?post:('ext node -> unit) ->
2267 val iter_tree_sibl :
2268 ?pre: ('ext node option -> 'ext node -> 'ext node option -> unit) ->
2269 ?post:('ext node option -> 'ext node -> 'ext node option -> unit) ->
2315 >The objects representing the document</TD