]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/DEVEL/pxp/pxp/doc/manual/html/x675.html
This commit was manufactured by cvs2svn to create branch
[helm.git] / helm / DEVEL / pxp / pxp / doc / manual / html / x675.html
diff --git a/helm/DEVEL/pxp/pxp/doc/manual/html/x675.html b/helm/DEVEL/pxp/pxp/doc/manual/html/x675.html
deleted file mode 100644 (file)
index cf3f473..0000000
+++ /dev/null
@@ -1,538 +0,0 @@
-<HTML
-><HEAD
-><TITLE
->Class-based processing of the node tree</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="Using PXP"
-HREF="c533.html"><LINK
-REL="PREVIOUS"
-TITLE="How to parse a document from an application"
-HREF="x550.html"><LINK
-REL="NEXT"
-TITLE="Example: An HTML backend for the readme
-DTD"
-HREF="x738.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="x550.html"
->Prev</A
-></TD
-><TD
-WIDTH="80%"
-ALIGN="center"
-VALIGN="bottom"
->Chapter 2. Using <SPAN
-CLASS="ACRONYM"
->PXP</SPAN
-></TD
-><TD
-WIDTH="10%"
-ALIGN="right"
-VALIGN="bottom"
-><A
-HREF="x738.html"
->Next</A
-></TD
-></TR
-></TABLE
-><HR
-ALIGN="LEFT"
-WIDTH="100%"></DIV
-><DIV
-CLASS="SECT1"
-><H1
-CLASS="SECT1"
-><A
-NAME="AEN675"
->2.3. Class-based processing of the node tree</A
-></H1
-><P
->By default, the parsed node tree consists of objects of the same class; this is
-a good design as long as you want only to access selected parts of the
-document. For complex transformations, it may be better to use different
-classes for objects describing different element types.</P
-><P
->For example, if the DTD declares the element types <TT
-CLASS="LITERAL"
->a</TT
->,
-<TT
-CLASS="LITERAL"
->b</TT
->, and <TT
-CLASS="LITERAL"
->c</TT
->, and if the task is to convert
-an arbitrary document into a printable format, the idea is to define for every
-element type a separate class that has a method <TT
-CLASS="LITERAL"
->print</TT
->. The
-classes are <TT
-CLASS="LITERAL"
->eltype_a</TT
->, <TT
-CLASS="LITERAL"
->eltype_b</TT
->, and
-<TT
-CLASS="LITERAL"
->eltype_c</TT
->, and every class implements
-<TT
-CLASS="LITERAL"
->print</TT
-> such that elements of the type corresponding to the
-class are converted to the output format.</P
-><P
->The parser supports such a design directly. As it is impossible to derive
-recursive classes in O'Caml<A
-NAME="AEN688"
-HREF="#FTN.AEN688"
->[1]</A
->, the specialized element classes cannot be formed by
-simply inheriting from the built-in classes of the parser and adding methods
-for customized functionality. To get around this limitation, every node of the
-document tree is represented by <I
-CLASS="EMPHASIS"
->two</I
-> objects, one called
-"the node" and containing the recursive definition of the tree, one called "the
-extension". Every node object has a reference to the extension, and the
-extension has a reference to the node. The advantage of this model is that it
-is now possible to customize the extension without affecting the typing
-constraints of the recursive node definition.</P
-><P
->Every extension must have the three methods <TT
-CLASS="LITERAL"
->clone</TT
->,
-<TT
-CLASS="LITERAL"
->node</TT
->, and <TT
-CLASS="LITERAL"
->set_node</TT
->. The method
-<TT
-CLASS="LITERAL"
->clone</TT
-> creates a deep copy of the extension object and
-returns it; <TT
-CLASS="LITERAL"
->node</TT
-> returns the node object for this extension
-object; and <TT
-CLASS="LITERAL"
->set_node</TT
-> is used to tell the extension object
-which node is associated with it, this method is automatically called when the
-node tree is initialized. The following definition is a good starting point
-for these methods; usually <TT
-CLASS="LITERAL"
->clone</TT
-> must be further refined
-when instance variables are added to the class:
-
-<PRE
-CLASS="PROGRAMLISTING"
->class custom_extension =
-  object (self)
-
-    val mutable node = (None : custom_extension node option)
-
-    method clone = {&#60; &#62;} 
-    method node =
-      match node with
-          None -&#62;
-            assert false
-        | Some n -&#62; n
-    method set_node n =
-      node &#60;- Some n
-
-  end</PRE
->
-
-This part of the extension is usually the same for all classes, so it is a good
-idea to consider <TT
-CLASS="LITERAL"
->custom_extension</TT
-> as the super-class of the
-further class definitions. Continuining the example of above, we can define the
-element type classes as follows:
-
-<PRE
-CLASS="PROGRAMLISTING"
->class virtual custom_extension =
-  object (self)
-    ... clone, node, set_node defined as above ...
-
-    method virtual print : out_channel -&#62; unit
-  end
-
-class eltype_a =
-  object (self)
-    inherit custom_extension
-    method print ch = ...
-  end
-
-class eltype_b =
-  object (self)
-    inherit custom_extension
-    method print ch = ...
-  end
-
-class eltype_c =
-  object (self)
-    inherit custom_extension
-    method print ch = ...
-  end</PRE
->
-
-The method <TT
-CLASS="LITERAL"
->print</TT
-> can now be implemented for every element
-type separately. Note that you get the associated node by invoking
-
-<PRE
-CLASS="PROGRAMLISTING"
->self # node</PRE
->
-
-and you get the extension object of a node <TT
-CLASS="LITERAL"
->n</TT
-> by writing 
-
-<PRE
-CLASS="PROGRAMLISTING"
->n # extension</PRE
->
-
-It is guaranteed that 
-
-<PRE
-CLASS="PROGRAMLISTING"
->self # node # extension == self</PRE
->
-
-always holds.</P
-><P
->Here are sample definitions of the <TT
-CLASS="LITERAL"
->print</TT
->
-methods:
-
-<PRE
-CLASS="PROGRAMLISTING"
->class eltype_a =
-  object (self)
-    inherit custom_extension
-    method print ch = 
-      (* Nodes &#60;a&#62;...&#60;/a&#62; are only containers: *)
-      output_string ch "(";
-      List.iter
-        (fun n -&#62; n # extension # print ch)
-        (self # node # sub_nodes);
-      output_string ch ")";
-  end
-
-class eltype_b =
-  object (self)
-    inherit custom_extension
-    method print ch =
-      (* Print the value of the CDATA attribute "print": *)
-      match self # node # attribute "print" with
-        Value s       -&#62; output_string ch s
-      | Implied_value -&#62; output_string ch "&#60;missing&#62;"
-      | Valuelist l   -&#62; assert false   
-                         (* not possible because the att is CDATA *)
-  end
-
-class eltype_c =
-  object (self)
-    inherit custom_extension
-    method print ch = 
-      (* Print the contents of this element: *)
-      output_string ch (self # node # data)
-  end
-
-class null_extension =
-  object (self)
-    inherit custom_extension
-    method print ch = assert false
-  end</PRE
-></P
-><P
->The remaining task is to configure the parser such that these extension classes
-are actually used. Here another problem arises: It is not possible to
-dynamically select the class of an object to be created. As workaround,
-<SPAN
-CLASS="ACRONYM"
->PXP</SPAN
-> allows the user to specify <I
-CLASS="EMPHASIS"
->exemplar objects</I
-> for
-the various element types; instead of creating the nodes of the tree by
-applying the <TT
-CLASS="LITERAL"
->new</TT
-> operator the nodes are produced by
-duplicating the exemplars. As object duplication preserves the class of the
-object, one can create fresh objects of every class for which previously an
-exemplar has been registered.</P
-><P
->Exemplars are meant as objects without contents, the only interesting thing is
-that exemplars are instances of a certain class. The creation of an exemplar
-for an element node can be done by:
-
-<PRE
-CLASS="PROGRAMLISTING"
->let element_exemplar = new element_impl extension_exemplar</PRE
->
-
-And a data node exemplar is created by:
-
-<PRE
-CLASS="PROGRAMLISTING"
->let data_exemplar = new data_impl extension_exemplar</PRE
->
-
-The classes <TT
-CLASS="LITERAL"
->element_impl</TT
-> and <TT
-CLASS="LITERAL"
->data_impl</TT
->
-are defined in the module <TT
-CLASS="LITERAL"
->Pxp_document</TT
->. The constructors
-initialize the fresh objects as empty objects, i.e. without children, without
-data contents, and so on. The <TT
-CLASS="LITERAL"
->extension_exemplar</TT
-> is the
-initial extension object the exemplars are associated with. </P
-><P
->Once the exemplars are created and stored somewhere (e.g. in a hash table), you
-can take an exemplar and create a concrete instance (with contents) by
-duplicating it. As user of the parser you are normally not concerned with this
-as this is part of the internal logic of the parser, but as background knowledge
-it is worthwhile to mention that the two methods
-<TT
-CLASS="LITERAL"
->create_element</TT
-> and <TT
-CLASS="LITERAL"
->create_data</TT
-> actually
-perform the duplication of the exemplar for which they are invoked,
-additionally apply modifications to the clone, and finally return the new
-object. Moreover, the extension object is copied, too, and the new node object
-is associated with the fresh extension object. Note that this is the reason why
-every extension object must have a <TT
-CLASS="LITERAL"
->clone</TT
-> method.</P
-><P
->The configuration of the set of exemplars is passed to the
-<TT
-CLASS="LITERAL"
->parse_document_entity</TT
-> function as third argument. In our
-example, this argument can be set up as follows:
-
-<PRE
-CLASS="PROGRAMLISTING"
->let spec =
-  make_spec_from_alist
-    ~data_exemplar:            (new data_impl (new null_extension))
-    ~default_element_exemplar: (new element_impl (new null_extension))
-    ~element_alist:
-       [ "a",  new element_impl (new eltype_a);
-         "b",  new element_impl (new eltype_b);
-         "c",  new element_impl (new eltype_c);
-       ]
-    ()</PRE
->
-
-The <TT
-CLASS="LITERAL"
->~element_alist</TT
-> function argument defines the mapping
-from element types to exemplars as associative list. The argument
-<TT
-CLASS="LITERAL"
->~data_exemplar</TT
-> specifies the exemplar for data nodes, and
-the <TT
-CLASS="LITERAL"
->~default_element_exemplar</TT
-> is used whenever the parser
-finds an element type for which the associative list does not define an
-exemplar. </P
-><P
->The configuration is now complete. You can still use the same parsing
-functions, only the initialization is a bit different. For example, call the
-parser by:
-
-<PRE
-CLASS="PROGRAMLISTING"
->let d = parse_document_entity default_config (from_file "doc.xml") spec</PRE
->
-
-Note that the resulting document <TT
-CLASS="LITERAL"
->d</TT
-> has a usable type;
-especially the <TT
-CLASS="LITERAL"
->print</TT
-> method we added is visible. So you can
-print your document by
-
-<PRE
-CLASS="PROGRAMLISTING"
->d # root # extension # print stdout</PRE
-></P
-><P
->This object-oriented approach looks rather complicated; this is mostly caused
-by working around some problems of the strict typing system of O'Caml. Some
-auxiliary concepts such as extensions were needed, but the practical
-consequences are low. In the next section, one of the examples of the
-distribution is explained, a converter from <I
-CLASS="EMPHASIS"
->readme</I
->
-documents to HTML.</P
-></DIV
-><H3
-CLASS="FOOTNOTES"
->Notes</H3
-><TABLE
-BORDER="0"
-CLASS="FOOTNOTES"
-WIDTH="100%"
-><TR
-><TD
-ALIGN="LEFT"
-VALIGN="TOP"
-WIDTH="5%"
-><A
-NAME="FTN.AEN688"
-HREF="x675.html#AEN688"
->[1]</A
-></TD
-><TD
-ALIGN="LEFT"
-VALIGN="TOP"
-WIDTH="95%"
-><P
->The problem is that the subclass is
-usually not a subtype in this case because O'Caml has a contravariant subtyping
-rule. </P
-></TD
-></TR
-></TABLE
-><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="x550.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="x738.html"
->Next</A
-></TD
-></TR
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
->How to parse a document from an application</TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="c533.html"
->Up</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
->Example: An HTML backend for the <I
-CLASS="EMPHASIS"
->readme</I
->
-DTD</TD
-></TR
-></TABLE
-></DIV
-></BODY
-></HTML
->
\ No newline at end of file