--- /dev/null
+<HTML
+><HEAD
+><TITLE
+>The class type node</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.46"><LINK
+REL="HOME"
+TITLE="The PXP user's guide"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="The objects representing the document"
+HREF="c893.html"><LINK
+REL="PREVIOUS"
+TITLE="The objects representing the document"
+HREF="c893.html"><LINK
+REL="NEXT"
+TITLE="The class type extension"
+HREF="x1439.html"><LINK
+REL="STYLESHEET"
+TYPE="text/css"
+HREF="markup.css"></HEAD
+><BODY
+CLASS="SECT1"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>The PXP user's guide</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="c893.html"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 3. The objects representing the document</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x1439.html"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECT1"
+><H1
+CLASS="SECT1"
+><A
+NAME="AEN939"
+>3.2. The class type <TT
+CLASS="LITERAL"
+>node</TT
+></A
+></H1
+><P
+> From <TT
+CLASS="LITERAL"
+>Pxp_document</TT
+>:
+
+<PRE
+CLASS="PROGRAMLISTING"
+>type node_type =
+ T_data
+| T_element of string
+| T_super_root
+| T_pinstr of string
+| T_comment
+<TT
+CLASS="REPLACEABLE"
+><I
+>and some other, reserved types</I
+></TT
+>
+;;
+
+class type [ 'ext ] node =
+ object ('self)
+ constraint 'ext = 'ext node #extension
+
+ <A
+NAME="TYPE-NODE-GENERAL.SIG"
+></A
+>(* <A
+HREF="x939.html#TYPE-NODE-GENERAL"
+><I
+><I
+>General observers</I
+></I
+></A
+> *)
+
+ method extension : 'ext
+ method dtd : dtd
+ method parent : 'ext node
+ method root : 'ext node
+ method sub_nodes : 'ext node list
+ method iter_nodes : ('ext node -> unit) -> unit
+ method iter_nodes_sibl :
+ ('ext node option -> 'ext node -> 'ext node option -> unit) -> unit
+ method node_type : node_type
+ method encoding : Pxp_types.rep_encoding
+ method data : string
+ method position : (string * int * int)
+ method comment : string option
+ method pinstr : string -> proc_instruction list
+ method pinstr_names : string list
+ method write : Pxp_types.output_stream -> Pxp_types.encoding -> unit
+
+ <A
+NAME="TYPE-NODE-ATTS.SIG"
+></A
+>(* <A
+HREF="x939.html#TYPE-NODE-ATTS"
+><I
+><I
+>Attribute observers</I
+></I
+></A
+> *)
+
+ method attribute : string -> Pxp_types.att_value
+ method required_string_attribute : string -> string
+ method optional_string_attribute : string -> string option
+ method required_list_attribute : string -> string list
+ method optional_list_attribute : string -> string list
+ method attribute_names : string list
+ method attribute_type : string -> Pxp_types.att_type
+ method attributes : (string * Pxp_types.att_value) list
+ method id_attribute_name : string
+ method id_attribute_value : string
+ method idref_attribute_names : string
+
+ <A
+NAME="TYPE-NODE-MODS.SIG"
+></A
+>(* <A
+HREF="x939.html#TYPE-NODE-MODS"
+><I
+><I
+>Modifying methods</I
+></I
+></A
+> *)
+
+ method add_node : ?force:bool -> 'ext node -> unit
+ method add_pinstr : proc_instruction -> unit
+ method delete : unit
+ method set_nodes : 'ext node list -> unit
+ method quick_set_attributes : (string * Pxp_types.att_value) list -> unit
+ method set_comment : string option -> unit
+
+ <A
+NAME="TYPE-NODE-CLONING.SIG"
+></A
+>(* <A
+HREF="x939.html#TYPE-NODE-CLONING"
+><I
+><I
+>Cloning methods</I
+></I
+></A
+> *)
+
+ method orphaned_clone : 'self
+ method orphaned_flat_clone : 'self
+ method create_element :
+ ?position:(string * int * int) ->
+ dtd -> node_type -> (string * string) list ->
+ 'ext node
+ method create_data : dtd -> string -> 'ext node
+ method keep_always_whitespace_mode : unit
+
+ <A
+NAME="TYPE-NODE-WEIRD.SIG"
+></A
+>(* <A
+HREF="x939.html#TYPE-NODE-WEIRD"
+><I
+><I
+>Validating methods</I
+></I
+></A
+> *)
+
+ method local_validate : ?use_dfa:bool -> unit -> unit
+
+ (* ... Internal methods are undocumented. *)
+
+ end
+;;</PRE
+>
+
+In the module <TT
+CLASS="LITERAL"
+>Pxp_types</TT
+> you can find another type
+definition that is important in this context:
+
+<PRE
+CLASS="PROGRAMLISTING"
+>type Pxp_types.att_value =
+ Value of string
+ | Valuelist of string list
+ | Implied_value
+;;</PRE
+></P
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="AEN958"
+>3.2.1. The structure of document trees</A
+></H2
+><P
+>A node represents either an element or a character data section. There are two
+classes implementing the two aspects of nodes: <TT
+CLASS="LITERAL"
+>element_impl</TT
+>
+and <TT
+CLASS="LITERAL"
+>data_impl</TT
+>. The latter class does not implement all
+methods because some methods do not make sense for data nodes.</P
+><P
+>(Note: PXP also supports a mode which forces that processing instructions and
+comments are represented as nodes of the document tree. However, these nodes
+are instances of <TT
+CLASS="LITERAL"
+>element_impl</TT
+> with node types
+<TT
+CLASS="LITERAL"
+>T_pinstr</TT
+> and <TT
+CLASS="LITERAL"
+>T_comment</TT
+>,
+respectively. This mode must be explicitly configured; the basic representation
+knows only element and data nodes.)</P
+><P
+>The following figure
+(<A
+HREF="x939.html#NODE-TERM"
+><I
+><I
+>A tree with element nodes, data nodes, and attributes</I
+><I
+></I
+></I
+></A
+>) shows an example how
+a tree is constructed from element and data nodes. The circular areas
+represent element nodes whereas the ovals denote data nodes. Only elements
+may have subnodes; data nodes are always leaves of the tree. The subnodes
+of an element can be either element or data nodes; in both cases the O'Caml
+objects storing the nodes have the class type <TT
+CLASS="LITERAL"
+>node</TT
+>.</P
+><P
+>Attributes (the clouds in the picture) are not directly
+integrated into the tree; there is always an extra link to the attribute
+list. This is also true for processing instructions (not shown in the
+picture). This means that there are separated access methods for attributes and
+processing instructions.</P
+><DIV
+CLASS="FIGURE"
+><A
+NAME="NODE-TERM"
+></A
+><P
+><B
+>Figure 3-1. A tree with element nodes, data nodes, and attributes</B
+></P
+><P
+><IMG
+SRC="pic/node_term.gif"></P
+></DIV
+><P
+>Only elements, data sections, attributes and processing
+instructions (and comments, if configured) can, directly or indirectly, occur
+in the document tree. It is impossible to add entity references to the tree; if
+the parser finds such a reference, not the reference as such but the referenced
+text (i.e. the tree representing the structured text) is included in the
+tree.</P
+><P
+>Note that the parser collapses as much data material into one
+data node as possible such that there are normally never two adjacent data
+nodes. This invariant is enforced even if data material is included by entity
+references or CDATA sections, or if a data sequence is interrupted by
+comments. So <TT
+CLASS="LITERAL"
+>a &amp; b <-- comment --> c <![CDATA[
+<> d]]></TT
+> is represented by only one data node, for
+instance. However, you can create document trees manually which break this
+invariant; it is only the way the parser forms the tree.</P
+><DIV
+CLASS="FIGURE"
+><A
+NAME="NODE-GENERAL"
+></A
+><P
+><B
+>Figure 3-2. Nodes are doubly linked trees</B
+></P
+><P
+><IMG
+SRC="pic/node_general.gif"></P
+></DIV
+><P
+>The node tree has links in both directions: Every node has a link to its parent
+(if any), and it has links to the subnodes (see
+figure <A
+HREF="x939.html#NODE-GENERAL"
+><I
+><I
+>Nodes are doubly linked trees</I
+><I
+></I
+></I
+></A
+>). Obviously,
+this doubly-linked structure simplifies the navigation in the tree; but has
+also some consequences for the possible operations on trees.</P
+><P
+>Because every node must have at most <I
+CLASS="EMPHASIS"
+>one</I
+> parent node,
+operations are illegal if they violate this condition. The following figure
+(<A
+HREF="x939.html#NODE-ADD"
+><I
+><I
+>A node can only be added if it is a root</I
+><I
+></I
+></I
+></A
+>) shows on the left side
+that node <TT
+CLASS="LITERAL"
+>y</TT
+> is added to <TT
+CLASS="LITERAL"
+>x</TT
+> as new subnode
+which is allowed because <TT
+CLASS="LITERAL"
+>y</TT
+> does not have a parent yet. The
+right side of the picture illustrates what would happen if <TT
+CLASS="LITERAL"
+>y</TT
+>
+had a parent node; this is illegal because <TT
+CLASS="LITERAL"
+>y</TT
+> would have two
+parents after the operation.</P
+><DIV
+CLASS="FIGURE"
+><A
+NAME="NODE-ADD"
+></A
+><P
+><B
+>Figure 3-3. A node can only be added if it is a root</B
+></P
+><P
+><IMG
+SRC="pic/node_add.gif"></P
+></DIV
+><P
+>The "delete" operation simply removes the links between two nodes. In the
+picture (<A
+HREF="x939.html#NODE-DELETE"
+><I
+><I
+>A deleted node becomes the root of the subtree</I
+><I
+></I
+></I
+></A
+>) the node
+<TT
+CLASS="LITERAL"
+>x</TT
+> is deleted from the list of subnodes of
+<TT
+CLASS="LITERAL"
+>y</TT
+>. After that, <TT
+CLASS="LITERAL"
+>x</TT
+> becomes the root of the
+subtree starting at this node.</P
+><DIV
+CLASS="FIGURE"
+><A
+NAME="NODE-DELETE"
+></A
+><P
+><B
+>Figure 3-4. A deleted node becomes the root of the subtree</B
+></P
+><P
+><IMG
+SRC="pic/node_delete.gif"></P
+></DIV
+><P
+>It is also possible to make a clone of a subtree; illustrated in
+<A
+HREF="x939.html#NODE-CLONE"
+><I
+><I
+>The clone of a subtree</I
+><I
+></I
+></I
+></A
+>. In this case, the
+clone is a copy of the original subtree except that it is no longer a
+subnode. Because cloning never keeps the connection to the parent, the clones
+are called <I
+CLASS="EMPHASIS"
+>orphaned</I
+>.</P
+><DIV
+CLASS="FIGURE"
+><A
+NAME="NODE-CLONE"
+></A
+><P
+><B
+>Figure 3-5. The clone of a subtree</B
+></P
+><P
+><IMG
+SRC="pic/node_clone.gif"></P
+></DIV
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="AEN1007"
+>3.2.2. The methods of the class type <TT
+CLASS="LITERAL"
+>node</TT
+></A
+></H2
+><A
+NAME="TYPE-NODE-GENERAL"
+></A
+><DIV
+CLASS="FORMALPARA"
+><P
+><B
+> <A
+HREF="x939.html#TYPE-NODE-GENERAL.SIG"
+>General observers</A
+>
+ . </B
+> <P
+></P
+><UL
+COMPACT="COMPACT"
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>extension</TT
+>: The reference to the extension object which
+belongs to this node (see ...).</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>dtd</TT
+>: Returns a reference to the global DTD. All nodes
+of a tree must share the same DTD.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>parent</TT
+>: Get the father node. Raises
+<TT
+CLASS="LITERAL"
+>Not_found</TT
+> in the case the node does not have a
+parent, i.e. the node is the root.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>root</TT
+>: Gets the reference to the root node of the tree.
+Every node is contained in a tree with a root, so this method always
+succeeds. Note that this method <I
+CLASS="EMPHASIS"
+>searches</I
+> the root,
+which costs time proportional to the length of the path to the root.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>sub_nodes</TT
+>: Returns references to the children. The returned
+list reflects the order of the children. For data nodes, this method returns
+the empty list.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>iter_nodes f</TT
+>: Iterates over the children, and calls
+<TT
+CLASS="LITERAL"
+>f</TT
+> for every child in turn. </P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>iter_nodes_sibl f</TT
+>: Iterates over the children, and calls
+<TT
+CLASS="LITERAL"
+>f</TT
+> for every child in turn. <TT
+CLASS="LITERAL"
+>f</TT
+> gets as
+arguments the previous node, the current node, and the next node.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>node_type</TT
+>: Returns either <TT
+CLASS="LITERAL"
+>T_data</TT
+> which
+means that the node is a data node, or <TT
+CLASS="LITERAL"
+>T_element n</TT
+>
+which means that the node is an element of type <TT
+CLASS="LITERAL"
+>n</TT
+>.
+If configured, possible node types are also <TT
+CLASS="LITERAL"
+>T_pinstr t</TT
+>
+indicating that the node represents a processing instruction with target
+<TT
+CLASS="LITERAL"
+>t</TT
+>, and <TT
+CLASS="LITERAL"
+>T_comment</TT
+> in which case the node
+is a comment.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>encoding</TT
+>: Returns the encoding of the strings.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>data</TT
+>: Returns the character data of this node and all
+children, concatenated as one string. The encoding of the string is what
+the method <TT
+CLASS="LITERAL"
+>encoding</TT
+> returns.
+- For data nodes, this method simply returns the represented characters.
+For elements, the meaning of the method has been extended such that it
+returns something useful, i.e. the effectively contained characters, without
+markup. (For <TT
+CLASS="LITERAL"
+>T_pinstr</TT
+> and <TT
+CLASS="LITERAL"
+>T_comment</TT
+>
+nodes, the method returns the empty string.)</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>position</TT
+>: If configured, this method returns the position of
+the element as triple (entity, line, byteposition). For data nodes, the
+position is not stored. If the position is not available the triple
+<TT
+CLASS="LITERAL"
+>"?", 0, 0</TT
+> is returned.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>comment</TT
+>: Returns <TT
+CLASS="LITERAL"
+>Some text</TT
+> for comment
+nodes, and <TT
+CLASS="LITERAL"
+>None</TT
+> for other nodes. The <TT
+CLASS="LITERAL"
+>text</TT
+>
+is everything between the comment delimiters <TT
+CLASS="LITERAL"
+><--</TT
+> and
+<TT
+CLASS="LITERAL"
+>--></TT
+>.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>pinstr n</TT
+>: Returns all processing instructions that are
+directly contained in this element and that have a <I
+CLASS="EMPHASIS"
+>target</I
+>
+specification of <TT
+CLASS="LITERAL"
+>n</TT
+>. The target is the first word after
+the <TT
+CLASS="LITERAL"
+><?</TT
+>.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>pinstr_names</TT
+>: Returns the list of all targets of processing
+instructions directly contained in this element.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>write s enc</TT
+>: Prints the node and all subnodes to the passed
+output stream as valid XML text, using the passed external encoding.</P
+></LI
+></UL
+>
+ </P
+></DIV
+><A
+NAME="TYPE-NODE-ATTS"
+></A
+><DIV
+CLASS="FORMALPARA"
+><P
+><B
+> <A
+HREF="x939.html#TYPE-NODE-ATTS.SIG"
+>Attribute observers</A
+>
+ . </B
+> <P
+></P
+><UL
+COMPACT="COMPACT"
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>attribute n</TT
+>: Returns the value of the attribute with name
+<TT
+CLASS="LITERAL"
+>n</TT
+>. This method returns a value for every declared
+attribute, and it raises <TT
+CLASS="LITERAL"
+>Not_found</TT
+> for any undeclared
+attribute. Note that it even returns a value if the attribute is actually
+missing but is declared as <TT
+CLASS="LITERAL"
+>#IMPLIED</TT
+> or has a default
+value. - Possible values are:
+ <P
+></P
+><UL
+COMPACT="COMPACT"
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>Implied_value</TT
+>: The attribute has been declared with the
+keyword <TT
+CLASS="LITERAL"
+>#IMPLIED</TT
+>, and the attribute is missing in the
+attribute list of this element.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>Value s</TT
+>: The attribute has been declared as type
+<TT
+CLASS="LITERAL"
+>CDATA</TT
+>, as <TT
+CLASS="LITERAL"
+>ID</TT
+>, as
+<TT
+CLASS="LITERAL"
+>IDREF</TT
+>, as <TT
+CLASS="LITERAL"
+>ENTITY</TT
+>, or as
+<TT
+CLASS="LITERAL"
+>NMTOKEN</TT
+>, or as enumeration or notation, and one of the two
+conditions holds: (1) The attribute value is present in the attribute list in
+which case the value is returned in the string <TT
+CLASS="LITERAL"
+>s</TT
+>. (2) The
+attribute has been omitted, and the DTD declared the attribute with a default
+value. The default value is returned in <TT
+CLASS="LITERAL"
+>s</TT
+>.
+- Summarized, <TT
+CLASS="LITERAL"
+>Value s</TT
+> is returned for non-implied, non-list
+attribute values.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>Valuelist l</TT
+>: The attribute has been declared as type
+<TT
+CLASS="LITERAL"
+>IDREFS</TT
+>, as <TT
+CLASS="LITERAL"
+>ENTITIES</TT
+>, or
+as <TT
+CLASS="LITERAL"
+>NMTOKENS</TT
+>, and one of the two conditions holds: (1) The
+attribute value is present in the attribute list in which case the
+space-separated tokens of the value are returned in the string list
+<TT
+CLASS="LITERAL"
+>l</TT
+>. (2) The attribute has been omitted, and the DTD declared
+the attribute with a default value. The default value is returned in
+<TT
+CLASS="LITERAL"
+>l</TT
+>.
+- Summarized, <TT
+CLASS="LITERAL"
+>Valuelist l</TT
+> is returned for all list-type
+attribute values.</P
+></LI
+></UL
+>
+
+Note that before the attribute value is returned, the value is normalized. This
+means that newlines are converted to spaces, and that references to character
+entities (i.e. <TT
+CLASS="LITERAL"
+>&#<TT
+CLASS="REPLACEABLE"
+><I
+>n</I
+></TT
+>;</TT
+>) and
+general entities
+(i.e. <TT
+CLASS="LITERAL"
+>&<TT
+CLASS="REPLACEABLE"
+><I
+>name</I
+></TT
+>;</TT
+>) are expanded;
+if necessary, expansion is performed recursively.</P
+><P
+>In well-formedness mode, there is no DTD which could declare an
+attribute. Because of this, every occuring attribute is considered as a CDATA
+attribute.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>required_string_attribute n</TT
+>: returns the Value attribute
+called n, or the Valuelist attribute as a string where the list elements
+are separated by spaces. If the attribute value is implied, or if the
+attribute does not exists, the method will fail. - This method is convenient
+if you expect a non-implied and non-list attribute value.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>optional_string_attribute n</TT
+>: returns the Value attribute
+called n, or the Valuelist attribute as a string where the list elements
+are separated by spaces. If the attribute value is implied, or if the
+attribute does not exists, the method returns None. - This method is
+convenient if you expect a non-list attribute value including the implied
+value.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>required_list_attribute n</TT
+>: returns the Valuelist attribute
+called n, or the Value attribute as a list with a single element.
+If the attribute value is implied, or if the
+attribute does not exists, the method will fail. - This method is
+convenient if you expect a list attribute value.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>optional_list_attribute n</TT
+>: returns the Valuelist attribute
+called n, or the Value attribute as a list with a single element.
+If the attribute value is implied, or if the
+attribute does not exists, an empty list will be returned. - This method
+is convenient if you expect a list attribute value or the implied value.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>attribute_names</TT
+>: returns the list of all attribute names of
+this element. As this is a validating parser, this list is equal to the
+list of declared attributes.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>attribute_type n</TT
+>: returns the type of the attribute called
+<TT
+CLASS="LITERAL"
+>n</TT
+>. See the module <TT
+CLASS="LITERAL"
+>Pxp_types</TT
+> for a
+description of the encoding of the types.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>attributes</TT
+>: returns the list of pairs of names and values
+for all attributes of
+this element.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>id_attribute_name</TT
+>: returns the name of the attribute that is
+declared with type ID. There is at most one such attribute. The method raises
+<TT
+CLASS="LITERAL"
+>Not_found</TT
+> if there is no declared ID attribute for the
+element type.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>id_attribute_value</TT
+>: returns the value of the attribute that
+is declared with type ID. There is at most one such attribute. The method raises
+<TT
+CLASS="LITERAL"
+>Not_found</TT
+> if there is no declared ID attribute for the
+element type.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>idref_attribute_names</TT
+>: returns the list of attribute names
+that are declared as IDREF or IDREFS.</P
+></LI
+></UL
+>
+ </P
+></DIV
+><A
+NAME="TYPE-NODE-MODS"
+></A
+><DIV
+CLASS="FORMALPARA"
+><P
+><B
+> <A
+HREF="x939.html#TYPE-NODE-MODS.SIG"
+>Modifying methods</A
+>
+ . </B
+>The following methods are only defined for element nodes (more exactly:
+the methods are defined for data nodes, too, but fail always).
+
+ <P
+></P
+><UL
+COMPACT="COMPACT"
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>add_node sn</TT
+>: Adds sub node <TT
+CLASS="LITERAL"
+>sn</TT
+> to the list
+of children. This operation is illustrated in the picture
+<A
+HREF="x939.html#NODE-ADD"
+><I
+><I
+>A node can only be added if it is a root</I
+><I
+></I
+></I
+></A
+>. This method expects that
+<TT
+CLASS="LITERAL"
+>sn</TT
+> is a root, and it requires that <TT
+CLASS="LITERAL"
+>sn</TT
+> and
+the current object share the same DTD.</P
+><P
+>Because <TT
+CLASS="LITERAL"
+>add_node</TT
+> is the method the parser itself uses
+to add new nodes to the tree, it performs by default some simple validation
+checks: If the content model is a regular expression, it is not allowed to add
+data nodes to this node unless the new nodes consist only of whitespace. In
+this case, the new data nodes are silently dropped (you can change this by
+invoking <TT
+CLASS="LITERAL"
+>keep_always_whitespace_mode</TT
+>).</P
+><P
+>If the document is flagged as stand-alone, these data nodes only
+containing whitespace are even forbidden if the element declaration is
+contained in an external entity. This case is detected and rejected.</P
+><P
+>If the content model is <TT
+CLASS="LITERAL"
+>EMPTY</TT
+>, it is not allowed to
+add any data node unless the data node is empty. In this case, the new data
+node is silently dropped.</P
+><P
+>These checks only apply if there is a DTD. In well-formedness mode, it is
+assumed that every element is declared with content model
+<TT
+CLASS="LITERAL"
+>ANY</TT
+> which prohibits any validation check. Furthermore, you
+turn these checks off by passing <TT
+CLASS="LITERAL"
+>~force:true</TT
+> as first
+argument.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>add_pinstr pi</TT
+>: Adds the processing instruction
+<TT
+CLASS="LITERAL"
+>pi</TT
+> to the list of processing instructions.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>delete</TT
+>: Deletes this node from the tree. After this
+operation, this node is no longer the child of the former father node; and the
+node loses the connection to the father as well. This operation is illustrated
+by the figure <A
+HREF="x939.html#NODE-DELETE"
+><I
+><I
+>A deleted node becomes the root of the subtree</I
+><I
+></I
+></I
+></A
+>.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>set_nodes nl</TT
+>: Sets the list of children to
+<TT
+CLASS="LITERAL"
+>nl</TT
+>. It is required that every member of <TT
+CLASS="LITERAL"
+>nl</TT
+>
+is a root, and that all members and the current object share the same DTD.
+Unlike <TT
+CLASS="LITERAL"
+>add_node</TT
+>, no validation checks are performed.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>quick_set_attributes atts</TT
+>: sets the attributes of this
+element to <TT
+CLASS="LITERAL"
+>atts</TT
+>. It is <I
+CLASS="EMPHASIS"
+>not</I
+> checked
+whether <TT
+CLASS="LITERAL"
+>atts</TT
+> matches the DTD or not; it is up to the
+caller of this method to ensure this. (This method may be useful to transform
+the attribute values, i.e. apply a mapping to every attribute.)</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>set_comment text</TT
+>: This method is only applicable to
+<TT
+CLASS="LITERAL"
+>T_comment</TT
+> nodes; it sets the comment text contained by such
+nodes. </P
+></LI
+></UL
+></P
+></DIV
+><A
+NAME="TYPE-NODE-CLONING"
+></A
+><DIV
+CLASS="FORMALPARA"
+><P
+><B
+> <A
+HREF="x939.html#TYPE-NODE-CLONING.SIG"
+>Cloning methods</A
+>
+ . </B
+> <P
+></P
+><UL
+COMPACT="COMPACT"
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>orphaned_clone</TT
+>: Returns a clone of the node and the complete
+tree below this node (deep clone). The clone does not have a parent (i.e. the
+reference to the parent node is <I
+CLASS="EMPHASIS"
+>not</I
+> cloned). While
+copying the subtree, strings are skipped; it is likely that the original tree
+and the copy tree share strings. Extension objects are cloned by invoking
+the <TT
+CLASS="LITERAL"
+>clone</TT
+> method on the original objects; how much of
+the extension objects is cloned depends on the implemention of this method.</P
+><P
+>This operation is illustrated by the figure
+<A
+HREF="x939.html#NODE-CLONE"
+><I
+><I
+>The clone of a subtree</I
+><I
+></I
+></I
+></A
+>.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>orphaned_flat_clone</TT
+>: Returns a clone of the node,
+but sets the list of sub nodes to [], i.e. the sub nodes are not cloned.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><A
+NAME="TYPE-NODE-METH-CREATE-ELEMENT"
+></A
+>
+<TT
+CLASS="LITERAL"
+>create_element dtd nt al</TT
+>: Returns a flat copy of this node
+(which must be an element) with the following modifications: The DTD is set to
+<TT
+CLASS="LITERAL"
+>dtd</TT
+>; the node type is set to <TT
+CLASS="LITERAL"
+>nt</TT
+>, and the
+new attribute list is set to <TT
+CLASS="LITERAL"
+>al</TT
+> (given as list of
+(name,value) pairs). The copy does not have children nor a parent. It does not
+contain processing instructions. See
+<A
+HREF="x939.html#TYPE-NODE-EX-CREATE-ELEMENT"
+>the example below</A
+>.</P
+><P
+>Note that you can specify the position of the new node
+by the optional argument <TT
+CLASS="LITERAL"
+>~position</TT
+>.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><A
+NAME="TYPE-NODE-METH-CREATE-DATA"
+></A
+>
+<TT
+CLASS="LITERAL"
+>create_data dtd cdata</TT
+>: Returns a flat copy of this node
+(which must be a data node) with the following modifications: The DTD is set to
+<TT
+CLASS="LITERAL"
+>dtd</TT
+>; the node type is set to <TT
+CLASS="LITERAL"
+>T_data</TT
+>; the
+attribute list is empty (data nodes never have attributes); the list of
+children and PIs is empty, too (same reason). The new node does not have a
+parent. The value <TT
+CLASS="LITERAL"
+>cdata</TT
+> is the new character content of the
+node. See
+<A
+HREF="x939.html#TYPE-NODE-EX-CREATE-DATA"
+>the example below</A
+>.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>keep_always_whitespace_mode</TT
+>: Even data nodes which are
+normally dropped because they only contain ignorable whitespace, can added to
+this node once this mode is turned on. (This mode is useful to produce
+canonical XML.)</P
+></LI
+></UL
+></P
+></DIV
+><A
+NAME="TYPE-NODE-WEIRD"
+></A
+><DIV
+CLASS="FORMALPARA"
+><P
+><B
+> <A
+HREF="x939.html#TYPE-NODE-WEIRD.SIG"
+>Validating methods</A
+>
+ . </B
+>There is one method which locally validates the node, i.e. checks whether the
+subnodes match the content model of this node.
+
+ <P
+></P
+><UL
+COMPACT="COMPACT"
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>local_validate</TT
+>: Checks that this node conforms to the
+DTD by comparing the type of the subnodes with the content model for this
+node. (Applications need not call this method unless they add new nodes
+themselves to the tree.)</P
+></LI
+></UL
+></P
+></DIV
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="AEN1252"
+>3.2.3. The class <TT
+CLASS="LITERAL"
+>element_impl</TT
+></A
+></H2
+><P
+>This class is an implementation of <TT
+CLASS="LITERAL"
+>node</TT
+> which
+realizes element nodes:
+
+<PRE
+CLASS="PROGRAMLISTING"
+>class [ 'ext ] element_impl : 'ext -> [ 'ext ] node</PRE
+> </P
+><DIV
+CLASS="FORMALPARA"
+><P
+><B
+>Constructor. </B
+>You can create a new instance by
+
+<PRE
+CLASS="PROGRAMLISTING"
+>new element_impl <TT
+CLASS="REPLACEABLE"
+><I
+>extension_object</I
+></TT
+></PRE
+>
+
+which creates a special form of empty element which already contains a
+reference to the <TT
+CLASS="REPLACEABLE"
+><I
+>extension_object</I
+></TT
+>, but is
+otherwise empty. This special form is called an
+<I
+CLASS="EMPHASIS"
+>exemplar</I
+>. The purpose of exemplars is that they serve as
+patterns that can be duplicated and filled with data. The method
+<A
+HREF="x939.html#TYPE-NODE-METH-CREATE-ELEMENT"
+><TT
+CLASS="LITERAL"
+>create_element</TT
+></A
+> is designed to perform this action.</P
+></DIV
+><A
+NAME="TYPE-NODE-EX-CREATE-ELEMENT"
+></A
+><DIV
+CLASS="FORMALPARA"
+><P
+><B
+>Example. </B
+>First, create an exemplar by
+
+<PRE
+CLASS="PROGRAMLISTING"
+>let exemplar_ext = ... in
+let exemplar = new element_impl exemplar_ext in</PRE
+>
+
+The <TT
+CLASS="LITERAL"
+>exemplar</TT
+> is not used in node trees, but only as
+a pattern when the element nodes are created:
+
+<PRE
+CLASS="PROGRAMLISTING"
+>let element = exemplar # <A
+HREF="x939.html#TYPE-NODE-METH-CREATE-ELEMENT"
+>create_element</A
+> dtd (T_element name) attlist </PRE
+>
+
+The <TT
+CLASS="LITERAL"
+>element</TT
+> is a copy of <TT
+CLASS="LITERAL"
+>exemplar</TT
+>
+(even the extension <TT
+CLASS="LITERAL"
+>exemplar_ext</TT
+> has been copied)
+which ensures that <TT
+CLASS="LITERAL"
+>element</TT
+> and its extension are objects
+of the same class as the exemplars; note that you need not to pass a
+class name or other meta information. The copy is initially connected
+with the <TT
+CLASS="LITERAL"
+>dtd</TT
+>, it gets a node type, and the attribute list
+is filled. The <TT
+CLASS="LITERAL"
+>element</TT
+> is now fully functional; it can
+be added to another element as child, and it can contain references to
+subnodes.</P
+></DIV
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="AEN1281"
+>3.2.4. The class <TT
+CLASS="LITERAL"
+>data_impl</TT
+></A
+></H2
+><P
+>This class is an implementation of <TT
+CLASS="LITERAL"
+>node</TT
+> which
+should be used for all character data nodes:
+
+<PRE
+CLASS="PROGRAMLISTING"
+>class [ 'ext ] data_impl : 'ext -> [ 'ext ] node</PRE
+> </P
+><DIV
+CLASS="FORMALPARA"
+><P
+><B
+>Constructor. </B
+>You can create a new instance by
+
+<PRE
+CLASS="PROGRAMLISTING"
+>new data_impl <TT
+CLASS="REPLACEABLE"
+><I
+>extension_object</I
+></TT
+></PRE
+>
+
+which creates an empty exemplar node which is connected to
+<TT
+CLASS="REPLACEABLE"
+><I
+>extension_object</I
+></TT
+>. The node does not contain a
+reference to any DTD, and because of this it cannot be added to node trees.</P
+></DIV
+><P
+>To get a fully working data node, apply the method
+<A
+HREF="x939.html#TYPE-NODE-METH-CREATE-DATA"
+><TT
+CLASS="LITERAL"
+>create_data</TT
+></A
+> to the exemplar (see example).</P
+><A
+NAME="TYPE-NODE-EX-CREATE-DATA"
+></A
+><DIV
+CLASS="FORMALPARA"
+><P
+><B
+>Example. </B
+>First, create an exemplar by
+
+<PRE
+CLASS="PROGRAMLISTING"
+>let exemplar_ext = ... in
+let exemplar = new exemplar_ext data_impl in</PRE
+>
+
+The <TT
+CLASS="LITERAL"
+>exemplar</TT
+> is not used in node trees, but only as
+a pattern when the data nodes are created:
+
+<PRE
+CLASS="PROGRAMLISTING"
+>let data_node = exemplar # <A
+HREF="x939.html#TYPE-NODE-METH-CREATE-DATA"
+>create_data</A
+> dtd "The characters contained in the data node" </PRE
+>
+
+The <TT
+CLASS="LITERAL"
+>data_node</TT
+> is a copy of <TT
+CLASS="LITERAL"
+>exemplar</TT
+>.
+The copy is initially connected
+with the <TT
+CLASS="LITERAL"
+>dtd</TT
+>, and it is filled with character material.
+The <TT
+CLASS="LITERAL"
+>data_node</TT
+> is now fully functional; it can
+be added to an element as child.</P
+></DIV
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="AEN1308"
+>3.2.5. The type <TT
+CLASS="LITERAL"
+>spec</TT
+></A
+></H2
+><P
+>The type <TT
+CLASS="LITERAL"
+>spec</TT
+> defines a way to handle the details of
+creating nodes from exemplars.
+
+<PRE
+CLASS="PROGRAMLISTING"
+>type 'ext spec
+constraint 'ext = 'ext node #extension
+
+val make_spec_from_mapping :
+ ?super_root_exemplar : 'ext node ->
+ ?comment_exemplar : 'ext node ->
+ ?default_pinstr_exemplar : 'ext node ->
+ ?pinstr_mapping : (string, 'ext node) Hashtbl.t ->
+ data_exemplar: 'ext node ->
+ default_element_exemplar: 'ext node ->
+ element_mapping: (string, 'ext node) Hashtbl.t ->
+ unit ->
+ 'ext spec
+
+val make_spec_from_alist :
+ ?super_root_exemplar : 'ext node ->
+ ?comment_exemplar : 'ext node ->
+ ?default_pinstr_exemplar : 'ext node ->
+ ?pinstr_alist : (string * 'ext node) list ->
+ data_exemplar: 'ext node ->
+ default_element_exemplar: 'ext node ->
+ element_alist: (string * 'ext node) list ->
+ unit ->
+ 'ext spec</PRE
+>
+
+The two functions <TT
+CLASS="LITERAL"
+>make_spec_from_mapping</TT
+> and
+<TT
+CLASS="LITERAL"
+>make_spec_from_alist</TT
+> create <TT
+CLASS="LITERAL"
+>spec</TT
+>
+values. Both functions are functionally equivalent and the only difference is
+that the first function prefers hashtables and the latter associative lists to
+describe mappings from names to exemplars.</P
+><P
+>You can specify exemplars for the various kinds of nodes that need to be
+generated when an XML document is parsed:
+
+<P
+></P
+><UL
+COMPACT="COMPACT"
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>~super_root_exemplar</TT
+>: This exemplar
+is used to create the super root. This special node is only created if the
+corresponding configuration option has been selected; it is the parent node of
+the root node which may be convenient if every working node must have a parent.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>~comment_exemplar</TT
+>: This exemplar is
+used when a comment node must be created. Note that such nodes are only created
+if the corresponding configuration option is "on".</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>~default_pinstr_exemplar</TT
+>: If a node
+for a processing instruction must be created, and the instruction is not listed
+in the table passed by <TT
+CLASS="LITERAL"
+>~pinstr_mapping</TT
+> or
+<TT
+CLASS="LITERAL"
+>~pinstr_alist</TT
+>, this exemplar is used.
+Again the configuration option must be "on" in order to create such nodes at
+all. </P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>~pinstr_mapping</TT
+> or
+<TT
+CLASS="LITERAL"
+>~pinstr_alist</TT
+>: Map the target names of processing
+instructions to exemplars. These mappings are only used when nodes for
+processing instructions are created.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>~data_exemplar</TT
+>: The exemplar for
+ordinary data nodes.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>~default_element_exemplar</TT
+>: This
+exemplar is used if an element node must be created, but the element type
+cannot be found in the tables <TT
+CLASS="LITERAL"
+>element_mapping</TT
+> or
+<TT
+CLASS="LITERAL"
+>element_alist</TT
+>.</P
+></LI
+><LI
+STYLE="list-style-type: disc"
+><P
+><TT
+CLASS="LITERAL"
+>~element_mapping</TT
+> or
+<TT
+CLASS="LITERAL"
+>~element_alist</TT
+>: Map the element types to exemplars. These
+mappings are used to create element nodes.</P
+></LI
+></UL
+>
+
+In most cases, you only want to create <TT
+CLASS="LITERAL"
+>spec</TT
+> values to pass
+them to the parser functions found in <TT
+CLASS="LITERAL"
+>Pxp_yacc</TT
+>. However, it
+might be useful to apply <TT
+CLASS="LITERAL"
+>spec</TT
+> values directly.</P
+><P
+>The following functions create various types of nodes by selecting the
+corresponding exemplar from the passed <TT
+CLASS="LITERAL"
+>spec</TT
+> value, and by
+calling <TT
+CLASS="LITERAL"
+>create_element</TT
+> or <TT
+CLASS="LITERAL"
+>create_data</TT
+> on
+the exemplar.
+
+<PRE
+CLASS="PROGRAMLISTING"
+>val create_data_node :
+ 'ext spec ->
+ dtd ->
+ (* data material: *) string ->
+ 'ext node
+
+val create_element_node :
+ ?position:(string * int * int) ->
+ 'ext spec ->
+ dtd ->
+ (* element type: *) string ->
+ (* attributes: *) (string * string) list ->
+ 'ext node
+
+val create_super_root_node :
+ ?position:(string * int * int) ->
+ 'ext spec ->
+ dtd ->
+ 'ext node
+
+val create_comment_node :
+ ?position:(string * int * int) ->
+ 'ext spec ->
+ dtd ->
+ (* comment text: *) string ->
+ 'ext node
+
+val create_pinstr_node :
+ ?position:(string * int * int) ->
+ 'ext spec ->
+ dtd ->
+ proc_instruction ->
+ 'ext node</PRE
+></P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="AEN1354"
+>3.2.6. Examples</A
+></H2
+><DIV
+CLASS="FORMALPARA"
+><P
+><B
+>Building trees. </B
+>Here is the piece of code that creates the tree of
+the figure <A
+HREF="x939.html#NODE-TERM"
+><I
+><I
+>A tree with element nodes, data nodes, and attributes</I
+><I
+></I
+></I
+></A
+>. The extension
+object and the DTD are beyond the scope of this example.
+
+<PRE
+CLASS="PROGRAMLISTING"
+>let exemplar_ext = ... (* some extension *) in
+let dtd = ... (* some DTD *) in
+
+let element_exemplar = new element_impl exemplar_ext in
+let data_exemplar = new data_impl exemplar_ext in
+
+let a1 = element_exemplar # create_element dtd (T_element "a") ["att", "apple"]
+and b1 = element_exemplar # create_element dtd (T_element "b") []
+and c1 = element_exemplar # create_element dtd (T_element "c") []
+and a2 = element_exemplar # create_element dtd (T_element "a") ["att", "orange"]
+in
+
+let cherries = data_exemplar # create_data dtd "Cherries" in
+let orange = data_exemplar # create_data dtd "An orange" in
+
+a1 # add_node b1;
+a1 # add_node c1;
+b1 # add_node a2;
+b1 # add_node cherries;
+a2 # add_node orange;</PRE
+>
+
+Alternatively, the last block of statements could also be written as:
+
+<PRE
+CLASS="PROGRAMLISTING"
+>a1 # set_nodes [b1; c1];
+b1 # set_nodes [a2; cherries];
+a2 # set_nodes [orange];</PRE
+>
+
+The root of the tree is <TT
+CLASS="LITERAL"
+>a1</TT
+>, i.e. it is true that
+
+<PRE
+CLASS="PROGRAMLISTING"
+>x # root == a1</PRE
+>
+
+for every x from { <TT
+CLASS="LITERAL"
+>a1</TT
+>, <TT
+CLASS="LITERAL"
+>a2</TT
+>,
+<TT
+CLASS="LITERAL"
+>b1</TT
+>, <TT
+CLASS="LITERAL"
+>c1</TT
+>, <TT
+CLASS="LITERAL"
+>cherries</TT
+>,
+<TT
+CLASS="LITERAL"
+>orange</TT
+> }.</P
+></DIV
+><P
+>Furthermore, the following properties hold:
+
+<PRE
+CLASS="PROGRAMLISTING"
+> a1 # attribute "att" = Value "apple"
+& a2 # attribute "att" = Value "orange"
+
+& cherries # data = "Cherries"
+& orange # data = "An orange"
+& a1 # data = "CherriesAn orange"
+
+& a1 # node_type = T_element "a"
+& a2 # node_type = T_element "a"
+& b1 # node_type = T_element "b"
+& c1 # node_type = T_element "c"
+& cherries # node_type = T_data
+& orange # node_type = T_data
+
+& a1 # sub_nodes = [ b1; c1 ]
+& a2 # sub_nodes = [ orange ]
+& b1 # sub_nodes = [ a2; cherries ]
+& c1 # sub_nodes = []
+& cherries # sub_nodes = []
+& orange # sub_nodes = []
+
+& a2 # parent == a1
+& b1 # parent == b1
+& c1 # parent == a1
+& cherries # parent == b1
+& orange # parent == a2</PRE
+></P
+><DIV
+CLASS="FORMALPARA"
+><P
+><B
+>Searching nodes. </B
+>The following function searches all nodes of a tree
+for which a certain condition holds:
+
+<PRE
+CLASS="PROGRAMLISTING"
+>let rec search p t =
+ if p t then
+ t :: search_list p (t # sub_nodes)
+ else
+ search_list p (t # sub_nodes)
+
+and search_list p l =
+ match l with
+ [] -> []
+ | t :: l' -> (search p t) @ (search_list p l')
+;;</PRE
+></P
+></DIV
+><P
+>For example, if you want to search all elements of a certain
+type <TT
+CLASS="LITERAL"
+>et</TT
+>, the function <TT
+CLASS="LITERAL"
+>search</TT
+> can be
+applied as follows:
+
+<PRE
+CLASS="PROGRAMLISTING"
+>let search_element_type et t =
+ search (fun x -> x # node_type = T_element et) t
+;;</PRE
+></P
+><DIV
+CLASS="FORMALPARA"
+><P
+><B
+>Getting attribute values. </B
+>Suppose we have the declaration:
+
+<PRE
+CLASS="PROGRAMLISTING"
+><!ATTLIST e a CDATA #REQUIRED
+ b CDATA #IMPLIED
+ c CDATA "12345"></PRE
+>
+
+In this case, every element <TT
+CLASS="LITERAL"
+>e</TT
+> must have an attribute
+<TT
+CLASS="LITERAL"
+>a</TT
+>, otherwise the parser would indicate an error. If
+the O'Caml variable <TT
+CLASS="LITERAL"
+>n</TT
+> holds the node of the tree
+corresponding to the element, you can get the value of the attribute
+<TT
+CLASS="LITERAL"
+>a</TT
+> by
+
+<PRE
+CLASS="PROGRAMLISTING"
+>let value_of_a = n # required_string_attribute "a"</PRE
+>
+
+which is more or less an abbreviation for
+
+<PRE
+CLASS="PROGRAMLISTING"
+>let value_of_a =
+ match n # attribute "a" with
+ Value s -> s
+ | _ -> assert false</PRE
+>
+
+- as the attribute is required, the <TT
+CLASS="LITERAL"
+>attribute</TT
+> method always
+returns a <TT
+CLASS="LITERAL"
+>Value</TT
+>.</P
+></DIV
+><P
+>In contrast to this, the attribute <TT
+CLASS="LITERAL"
+>b</TT
+> can be
+omitted. In this case, the method <TT
+CLASS="LITERAL"
+>required_string_attribute</TT
+>
+works only if the attribute is there, and the method will fail if the attribute
+is missing. To get the value, you can apply the method
+<TT
+CLASS="LITERAL"
+>optional_string_attribute</TT
+>:
+
+<PRE
+CLASS="PROGRAMLISTING"
+>let value_of_b = n # optional_string_attribute "b"</PRE
+>
+
+Now, <TT
+CLASS="LITERAL"
+>value_of_b</TT
+> is of type <TT
+CLASS="LITERAL"
+>string option</TT
+>,
+and <TT
+CLASS="LITERAL"
+>None</TT
+> represents the omitted attribute. Alternatively,
+you could also use <TT
+CLASS="LITERAL"
+>attribute</TT
+>:
+
+<PRE
+CLASS="PROGRAMLISTING"
+>let value_of_b =
+ match n # attribute "b" with
+ Value s -> Some s
+ | Implied_value -> None
+ | _ -> assert false</PRE
+></P
+><P
+>The attribute <TT
+CLASS="LITERAL"
+>c</TT
+> behaves much like
+<TT
+CLASS="LITERAL"
+>a</TT
+>, because it has always a value. If the attribute is
+omitted, the default, here "12345", will be returned instead. Because of this,
+you can again use <TT
+CLASS="LITERAL"
+>required_string_attribute</TT
+> to get the
+value.</P
+><P
+>The type <TT
+CLASS="LITERAL"
+>CDATA</TT
+> is the most general string
+type. The types <TT
+CLASS="LITERAL"
+>NMTOKEN</TT
+>, <TT
+CLASS="LITERAL"
+>ID</TT
+>,
+<TT
+CLASS="LITERAL"
+>IDREF</TT
+>, <TT
+CLASS="LITERAL"
+>ENTITY</TT
+>, and all enumerators and
+notations are special forms of string types that restrict the possible
+values. From O'Caml, they behave like <TT
+CLASS="LITERAL"
+>CDATA</TT
+>, i.e. you can
+use the methods <TT
+CLASS="LITERAL"
+>required_string_attribute</TT
+> and
+<TT
+CLASS="LITERAL"
+>optional_string_attribute</TT
+>, too.</P
+><P
+>In contrast to this, the types <TT
+CLASS="LITERAL"
+>NMTOKENS</TT
+>,
+<TT
+CLASS="LITERAL"
+>IDREFS</TT
+>, and <TT
+CLASS="LITERAL"
+>ENTITIES</TT
+> mean lists of
+strings. Suppose we have the declaration:
+
+<PRE
+CLASS="PROGRAMLISTING"
+><!ATTLIST f d NMTOKENS #REQUIRED
+ e NMTOKENS #IMPLIED></PRE
+>
+
+The type <TT
+CLASS="LITERAL"
+>NMTOKENS</TT
+> stands for lists of space-separated
+tokens; for example the value <TT
+CLASS="LITERAL"
+>"1 abc 23ef"</TT
+> means the list
+<TT
+CLASS="LITERAL"
+>["1"; "abc"; "23ef"]</TT
+>. (Again, <TT
+CLASS="LITERAL"
+>IDREFS</TT
+>
+and <TT
+CLASS="LITERAL"
+>ENTITIES</TT
+> have more restricted values.) To get the
+value of attribute <TT
+CLASS="LITERAL"
+>d</TT
+>, one can use
+
+<PRE
+CLASS="PROGRAMLISTING"
+>let value_of_d = n # required_list_attribute "d"</PRE
+>
+
+or
+
+<PRE
+CLASS="PROGRAMLISTING"
+>let value_of_d =
+ match n # attribute "d" with
+ Valuelist l -> l
+ | _ -> assert false</PRE
+>
+
+As <TT
+CLASS="LITERAL"
+>d</TT
+> is required, the attribute cannot be omitted, and
+the <TT
+CLASS="LITERAL"
+>attribute</TT
+> method returns always a
+<TT
+CLASS="LITERAL"
+>Valuelist</TT
+>. </P
+><P
+>For optional attributes like <TT
+CLASS="LITERAL"
+>e</TT
+>, apply
+
+<PRE
+CLASS="PROGRAMLISTING"
+>let value_of_e = n # optional_list_attribute "e"</PRE
+>
+
+or
+
+<PRE
+CLASS="PROGRAMLISTING"
+>let value_of_e =
+ match n # attribute "e" with
+ Valuelist l -> l
+ | Implied_value -> []
+ | _ -> assert false</PRE
+>
+
+Here, the case that the attribute is missing counts like the empty list.</P
+></DIV
+><DIV
+CLASS="SECT2"
+><H2
+CLASS="SECT2"
+><A
+NAME="AEN1435"
+>3.2.7. Iterators</A
+></H2
+><P
+>There are also several iterators in Pxp_document; please see
+the mli file for details. You can find examples for them in the
+"simple_transformation" directory.
+
+<PRE
+CLASS="PROGRAMLISTING"
+>val find : ?deeply:bool ->
+ f:('ext node -> bool) -> 'ext node -> 'ext node
+
+val find_all : ?deeply:bool ->
+ f:('ext node -> bool) -> 'ext node -> 'ext node list
+
+val find_element : ?deeply:bool ->
+ string -> 'ext node -> 'ext node
+
+val find_all_elements : ?deeply:bool ->
+ string -> 'ext node -> 'ext node list
+
+exception Skip
+val map_tree : pre:('exta node -> 'extb node) ->
+ ?post:('extb node -> 'extb node) ->
+ 'exta node ->
+ 'extb node
+
+
+val map_tree_sibl :
+ pre: ('exta node option -> 'exta node -> 'exta node option ->
+ 'extb node) ->
+ ?post:('extb node option -> 'extb node -> 'extb node option ->
+ 'extb node) ->
+ 'exta node ->
+ 'extb node
+
+val iter_tree : ?pre:('ext node -> unit) ->
+ ?post:('ext node -> unit) ->
+ 'ext node ->
+ unit
+
+val iter_tree_sibl :
+ ?pre: ('ext node option -> 'ext node -> 'ext node option -> unit) ->
+ ?post:('ext node option -> 'ext node -> 'ext node option -> unit) ->
+ 'ext node ->
+ unit</PRE
+></P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="c893.html"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x1439.html"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>The objects representing the document</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c893.html"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>The class type <TT
+CLASS="LITERAL"
+>extension</TT
+></TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file