module Xtmpl:sig..end
Rewrite XML Xtmpl.trees using Xtmpl.callback rules
provided by the Xtmpl.env environment.
A complete description of the templating rules is available in the
Templating engine section below.
exception No_change
typename =string * string
typeattribute =name * string
type env
typecallback =env -> attribute list -> tree list -> tree list
type tree =
| |
E of |
| |
D of |
An Xtmpl.env is a Xtmpl.name-to-Xtmpl.callback associative map. In addition
to basic manipulation functions, the functions Xtmpl.env_add_att and
Xtmpl.env_of_list provide convenient shortcuts for common operations.
The environments are immutable, all mutating operations return new
environments.
val env_empty : envXtmpl.tag_main to a function returning its subnodes.val env_add : ?prefix:string -> string -> callback -> env -> env
env_add "double" (fun _ _ xml -> xml @ xml) binds the key
("", "double") to a callback that doubles an XML subtree.
env_add ~prefix: "foo" "double" (fun _ _ xml -> xml @ xml) does the same but
for the key ("foo", "double").
If the same key was already bound, the previous binding is
replaced.
prefix : is "" by default.val env_get : name -> env -> callback option
If the binding is not found, returns None.
val string_of_env : env -> stringval env_add_att : ?prefix:string -> string -> string -> env -> envThe most frequent operation performed by a callback is to return a constant XML subtree. This convenience function lets you provide the XML subtree as a string.
env_add_att "logo" "<img src=\"logo.png\"/>" env binds the key
("","logo") to a callback that returns an XHTML image tag.
Note that the provided XML is automatically wrapped in the
Xtmpl.tag_main tag, which will cause the corresponding
templating rules to be applied to it
val env_of_list : ?env:env -> (name * callback) list -> env
This convenience function saves you the effort of calling
Xtmpl.env_add several times yourself.
env_of_list ~env:env [ (ns1, k1), f1 ; (ns2, k2), f2 ] is equivalent to
env_add ~prefix: ns1 k1 f1 (env_add ~prefix: ns2 k2 f2 env). This means that one key
is present twice in the list, the first association in the list
will hide the second one in the resulting environment.
env : The environment to which bindings are added. If
not provided, Xtmpl.env_empty is used.val tag_main : string"main_". It is used when parsing a
string as an XML tree, to ensure that we will parse a tree and
not a list of trees. For this purpose, the tag is used to enclosed
a string before parsing it.
Used by Xtmpl.env_add_att, Xtmpl.xml_of_string and, most importantly,
by the apply_* functions.
val tag_env : string"env_".
See the template rules in the templating engine section below for more
information about this tag.
val string_of_xml : tree -> string
The returned string does not include the initial <?xml ... ?>.
val string_of_xmls : tree list -> stringXtmpl.string_of_xml to concatenate a list of xml trees into one string,
with no separator.val xml_of_string : ?add_main:bool -> string -> treeFailure when a parsing error occurs, includes the source string.val xml_of_file : string -> treeXtmpl.xml_of_string but read from a file.
The apply_* functions apply a given environment to XML tree(s). These
trees are given as parameter (Xtmpl.apply_to_xmls) or can be read from a
file (Xtmpl.apply_to_file), or a string (Xtmpl.apply_to_string).
The functions return the result of the rewrite as XML trees, or
can write it to a file (Xtmpl.apply_into_file).
The rewrite rules are applied until a fix-point is reached.
I. A single iteration descends recursively into the XML tree. If an element has a callback associated in the environment, then the callback is applied to the node's attributes and children.
Example: consider the following XML:
<album author="Rammstein" name="Reise, Reise"> <track>Los</track> <track>Mein Teil</track> </album>
This would look for a callback bound to ("","album") in the environment
and call it using callback env [("","author"),"Rammstein"; ("","name"),"Reise, Reise"] xml
where env is the current environment and xml represents the
two children <track>..</track> elements.
II. The callback returns a new list of elements that is used instead of the old element.
Example: assuming that env_add "x2" (fun _ _ xml -> xml @ xml),
then <x2>A</x2> is rewritten as AA.
III. The engine then recursively descends into those replaced elements (this means that a poorly conceived rule set may well never terminate).
Example: <x2><x2>A</x2></x2> is first rewritten as
<x2>A</x2><x2>A</x2>, and then as AAAA.
IV. The env_ and main_ elements (see Xtmpl.tag_env
and Xtmpl.tag_main) are a special case: both are automatically
replaced with their children (as if their callback was
(fun _ _ xml -> xml)).
env_ effectively changes the environment
used when processing its children by adding the bindings defined by
its arguments (using Xtmpl.env_add_att, hence the name).
Example: <env_ a="<b>A</b>"><a/></env_> is
replaced by <a/>, which in turn is replaced by
<b>A</b>.
V. If an element has a defer_ attribute (that is greater
than zero), then it is not processed and the attribute is decremented
by one, and the process recursively applies to its children.
Example: <x2 defer_="1"><x2>A</x2></x2> is rewritten as
<x2 defer_="0">AA</x2>. The next iteration will effectively apply the
rule to the node and return AAAA.
val apply_to_string : env -> string -> tree list
See above for how an iteration is applied.
val apply_to_file : env -> string -> tree listXtmpl.apply_to_string, but reads the XML from a file.val apply_to_xmls : env -> tree list -> tree listXtmpl.apply_to_string, but applies to a list of XML trees.val apply_into_file : ?head:string -> env -> infile:string -> outfile:string -> unitXtmpl.apply_to_file, but writes the result back to a file.
For instance, apply_to_file env ~infile:"source.xml" ~outfile: "dest.xml".
head : Prepend this string to the XML that is output
to the file. By default, nothing is prepended.val apply_string_into_file : ?head:string -> env -> outfile:string -> string -> unitXtmpl.apply_into_file, but read the XML from a string instead of a file.
Several useful functions when workin with XML.
val get_arg : attribute list -> name -> string option
This performs the same as List.assoc, but returns an optional string
instead of raising Not_found.
val string_of_args : attribute list -> string
string_of_args ["a","x";"b","y"] returns a="x" b="y". Note that
the argument names are output verbatim, but the argument values are
escaped with the %S format.
val opt_arg : attribute list -> ?def:string -> name -> string
This performs the same as List.assoc, but returns the provided
default value instead of raising Not_found.
def : Default value, returned for missing bindings. If not
provided, an empty string is used.