On Type-7
[yaz-moved-to-github.git] / doc / tools.xml
index 4b0d62b..9ebc4dd 100644 (file)
@@ -1,6 +1,5 @@
-<!-- $Id: tools.xml,v 1.59 2007-05-04 12:24:15 adam Exp $ -->
  <chapter id="tools"><title>Supporting Tools</title>
-  
+
   <para>
    In support of the service API - primarily the ASN module, which
    provides the pro-grammatic interface to the Z39.50 APDUs, &yaz; contains
@@ -41,7 +40,7 @@
      </para>
     </note>
     <para>
-     The PQF is defined by the pquery module in the YAZ library. 
+     The PQF is defined by the pquery module in the YAZ library.
      There are two sets of function that have similar behavior. First
      set operates on a PQF parser handle, second set doesn't. First set
      set of functions are more flexible than the second set. Second set
     <synopsis>
      #include &lt;yaz/pquery.h&gt;
 
-     YAZ_PQF_Parser yaz_pqf_create (void);
+     YAZ_PQF_Parser yaz_pqf_create(void);
 
-     void yaz_pqf_destroy (YAZ_PQF_Parser p);
+     void yaz_pqf_destroy(YAZ_PQF_Parser p);
 
-     Z_RPNQuery *yaz_pqf_parse (YAZ_PQF_Parser p, ODR o, const char *qbuf);
+     Z_RPNQuery *yaz_pqf_parse(YAZ_PQF_Parser p, ODR o, const char *qbuf);
 
-     Z_AttributesPlusTerm *yaz_pqf_scan (YAZ_PQF_Parser p, ODR o,
+     Z_AttributesPlusTerm *yaz_pqf_scan(YAZ_PQF_Parser p, ODR o,
                           Odr_oid **attributeSetId, const char *qbuf);
 
-
-     int yaz_pqf_error (YAZ_PQF_Parser p, const char **msg, size_t *off);
+     int yaz_pqf_error(YAZ_PQF_Parser p, const char **msg, size_t *off);
     </synopsis>
     <para>
      A PQF parser is created and destructed by functions
@@ -74,7 +72,7 @@
      a Z39.50 RPN Query is returned which is created using ODR stream
      <literal>o</literal>. If parsing failed, a NULL pointer is
      returned.
-     Function <function>yaz_pqf_scan</function> takes a scan query in 
+     Function <function>yaz_pqf_scan</function> takes a scan query in
      <literal>qbuf</literal>. If parsing was successful, the function
      returns attributes plus term pointer and modifies
      <literal>attributeSetId</literal> to hold attribute set for the
     <synopsis>
      #include &lt;yaz/pquery.h&gt;
 
-     Z_RPNQuery *p_query_rpn (ODR o, oid_proto proto, const char *qbuf);
+     Z_RPNQuery *p_query_rpn(ODR o, oid_proto proto, const char *qbuf);
 
-     Z_AttributesPlusTerm *p_query_scan (ODR o, oid_proto proto,
+     Z_AttributesPlusTerm *p_query_scan(ODR o, oid_proto proto,
                              Odr_oid **attributeSetP, const char *qbuf);
 
-     int p_query_attset (const char *arg);
+     int p_query_attset(const char *arg);
     </synopsis>
     <para>
      The function <function>p_query_rpn()</function> takes as arguments an
     <para>
      If the parse went well, <function>p_query_rpn()</function> returns a
      pointer to a <literal>Z_RPNQuery</literal> structure which can be
-     placed directly into a <literal>Z_SearchRequest</literal>. 
+     placed directly into a <literal>Z_SearchRequest</literal>.
      If parsing failed, due to syntax error, a NULL pointer is returned.
     </para>
     <para>
     </para>
 
     <para>
-     The @attr operator is followed by an attribute specification 
+     The @attr operator is followed by an attribute specification
      (<literal>attr-spec</literal> above). The specification consists
      of an optional attribute set, an attribute type-value pair and
      a sub-query. The attribute type-value pair is packed in one string:
      is used.  This is the only encoding allowed in both versions 2 and 3
      of the Z39.50 standard.
     </para>
-    
+
     <sect3 id="PQF-prox">
       <title>Using Proximity Operators with PQF</title>
       <note>
       <para>
         The proximity operator <literal>@prox</literal> is a special
         and more restrictive version of the conjunction operator
-        <literal>@and</literal>.  Its semantics are described in 
+        <literal>@and</literal>.  Its semantics are described in
        section 3.7.2 (Proximity) of Z39.50 the standard itself, which
         can be read on-line at
        <ulink url="&url.z39.50.proximity;"/>
       <para>
        <screen>
        @or @and bob dylan @set Result-1
-       
+
        @attr 4=1 @and @attr 1=1 "bob dylan" @attr 1=4 "slow train coming"
-       
+
        @and @attr 2=4 @attr gils 1=2038 -114 @attr 2=2 @attr gils 1=2039 -109
       </screen>
        <note>
      symbolic language for expressing boolean query structures.
     </para>
 
-    <para>
-     The EUROPAGATE research project working under the Libraries programme
-     of the European Commission's DG XIII has, amongst other useful tools,
-     implemented a general-purpose CCL parser which produces an output
-     structure that can be trivially converted to the internal RPN
-     representation of &yaz; (The <literal>Z_RPNQuery</literal> structure).
-     Since the CCL utility - along with the rest of the software
-     produced by EUROPAGATE - is made freely available on a liberal
-     license, it is included as a supplement to &yaz;.
-    </para>
-
     <sect3 id="ccl.syntax">
      <title>CCL Syntax</title>
 
       -- Proximity operator
 
      </screen>
-     
+
      <example id="example.ccl.queries">
       <title>CCL queries</title>
       <para>
        The following queries are all valid:
       </para>
-      
+
       <screen>
        dylan
-       
+
        "bob dylan"
-       
+
        dylan or zimmerman
-       
+
        set=1
-       
+
        (dylan and bob) or set=1
-       
+
+       righttrunc?
+
+       "notrunc?"
+
+       singlechar#mask
+
       </screen>
       <para>
        Assuming that the qualifiers <literal>ti</literal>,
        <literal>au</literal>
        and <literal>date</literal> are defined we may use:
       </para>
-      
+
       <screen>
        ti=self portrait
-       
+
        au=(bob dylan and slow train coming)
 
        date>1980 and (ti=((self portrait)))
-       
+
       </screen>
      </example>
-     
+
     </sect3>
     <sect3 id="ccl.qualifiers">
      <title>CCL Qualifiers</title>
-     
+
      <para>
       Qualifiers are used to direct the search to a particular searchable
       index, such as title (ti) and author indexes (au). The CCL standard
       <para>
        A qualifier specification is of the form:
       </para>
-      
+
       <para>
-       <replaceable>qualifier-name</replaceable>  
+       <replaceable>qualifier-name</replaceable>
        [<replaceable>attributeset</replaceable><literal>,</literal>]<replaceable>type</replaceable><literal>=</literal><replaceable>val</replaceable>
-       [<replaceable>attributeset</replaceable><literal>,</literal>]<replaceable>type</replaceable><literal>=</literal><replaceable>val</replaceable> ...      
+       [<replaceable>attributeset</replaceable><literal>,</literal>]<replaceable>type</replaceable><literal>=</literal><replaceable>val</replaceable> ...
       </para>
-      
+
       <para>
        where <replaceable>qualifier-name</replaceable> is the name of the
        qualifier to be used (eg. <literal>ti</literal>),
        <replaceable>val</replaceable> is attribute value.
        The <replaceable>type</replaceable> can be specified as an
        integer or as it be specified either as a single-letter:
-       <literal>u</literal> for use, 
+       <literal>u</literal> for use,
        <literal>r</literal> for relation,<literal>p</literal> for position,
        <literal>s</literal> for structure,<literal>t</literal> for truncation
        or <literal>c</literal> for completeness.
        </table>
       </para>
       <para>
-       Refer to the complete
+       Refer to <xref linkend="bib1"/> or the complete
        <ulink url="&url.z39.50.attset.bib1;">list of Bib-1 attributes</ulink>
       </para>
       <para>
-       It is also possible to specify non-numeric attribute values, 
+       It is also possible to specify non-numeric attribute values,
        which are used in combination with certain types.
        The special combinations are:
-       
+
        <table id="ccl.special.attribute.combos">
        <title>Special attribute combos</title>
        <tgroup cols="2">
            This does not set the structure at all.
           </entry>
          </row>
-         
+
          <row><entry><literal>s=ol</literal></entry><entry>
            Each token in the term is ORed. (or-list).
            This does not set the structure at all.
           </entry>
          </row>
-         
+
+         <row><entry><literal>s=ag</literal></entry><entry>
+           Tokens that appears as phrases (with blank in them) gets
+           structure phrase attached (4=1). Tokens that appear to be words
+           gets structure word attached (4=2). Phrases and words are
+           ANDed. This is a variant of s=al and s=pw, with the main
+           difference that words are not split (with operator AND)
+           but instead kept in one RPN token. This facility appeared
+           in YAZ 4.2.38.
+          </entry>
+         </row>
+
          <row><entry><literal>r=o</literal></entry><entry>
            Allows ranges and the operators greather-than, less-than, ...
            equals.
            This sets Bib-1 relation attribute accordingly (relation
            ordered). A query construct is only treated as a range if
            dash is used and that is surrounded by white-space. So
-           <literal>-1980</literal> is treated as term 
+           <literal>-1980</literal> is treated as term
            <literal>"-1980"</literal> not <literal>&lt;= 1980</literal>.
            If <literal>- 1980</literal> is used, however, that is
            treated as a range.
           </entry>
          </row>
-         
+
          <row><entry><literal>r=r</literal></entry><entry>
            Similar to <literal>r=o</literal> but assumes that terms
            are non-negative (not prefixed with <literal>-</literal>).
            <literal>r=r</literal> is available in YAZ 2.0.24 or later.
           </entry>
          </row>
-         
+
          <row><entry><literal>t=l</literal></entry><entry>
            Allows term to be left-truncated.
            If term is of the form <literal>?x</literal>, the resulting
            Type-1 term is <literal>x</literal> and truncation is left.
           </entry>
          </row>
-         
+
          <row><entry><literal>t=r</literal></entry><entry>
            Allows term to be right-truncated.
            If term is of the form <literal>x?</literal>, the resulting
            Type-1 term is <literal>x</literal> and truncation is right.
           </entry>
          </row>
-         
+
          <row><entry><literal>t=n</literal></entry><entry>
            If term is does not include <literal>?</literal>, the
            truncation attribute is set to none (100).
           </entry>
          </row>
-         
+
          <row><entry><literal>t=b</literal></entry><entry>
            Allows term to be both left&amp;right truncated.
            If term is of the form <literal>?x?</literal>, the
            set to both left&amp;right.
           </entry>
          </row>
+
+         <row><entry><literal>t=x</literal></entry><entry>
+           Allows masking anywhere in a term, thus fully supporting
+           # (mask one character) and ? (zero or more of any).
+           If masking is used, trunction is set to 102 (regexp-1 in term)
+           and the term is converted accordingly to a regular expression.
+          </entry>
+         </row>
+
+         <row><entry><literal>t=z</literal></entry><entry>
+           Allows masking anywhere in a term, thus fully supporting
+           # (mask one character) and ? (zero or more of any).
+           If masking is used, trunction is set to 104 (Z39.58 in term)
+           and the term is converted accordingly to Z39.58 masking term -
+           actually the same truncation as CCL itself.
+          </entry>
+         </row>
+
         </tbody>
        </tgroup>
        </table>
        <para>
        Consider the following definition:
        </para>
-       
+
        <screen>
        ti       u=4 s=1
        au       u=1 s=1
        date     u=30 r=o
       </screen>
        <para>
-       <literal>ti</literal> and <literal>au</literal> both set 
+       <literal>ti</literal> and <literal>au</literal> both set
        structure attribute to phrase (s=1).
        <literal>ti</literal>
        sets the use-attribute to 4. <literal>au</literal> sets the
        </para>
        <para>
        You can combine attributes. To Search for "ranked title" you
-       can do 
+       can do
        <screen>
         ti,ranked=knuth computer
        </screen>
        A qualifier alias is of the form:
       </para>
       <para>
-       <replaceable>q</replaceable>  
+       <replaceable>q</replaceable>
        <replaceable>q1</replaceable> <replaceable>q2</replaceable> ..
       </para>
       <para>
        which declares <replaceable>q</replaceable> to
-       be an alias for <replaceable>q1</replaceable>, 
+       be an alias for <replaceable>q1</replaceable>,
        <replaceable>q2</replaceable>... such that the CCL
        query <replaceable>q=x</replaceable> is equivalent to
        <replaceable>q1=x or q2=x or ...</replaceable>.
          <entry><literal>?</literal></entry>
         </row>
         <row>
+         <entry>mask</entry>
+         <entry>Masking character. Requires YAZ 4.2.58 or later</entry>
+         <entry><literal>#</literal></entry>
+        </row>
+        <row>
          <entry>field</entry>
          <entry>Specifies how multiple fields are to be
           combined. There are two modes: <literal>or</literal>:
         </row>
         <row>
          <entry>case</entry>
-         <entry>Specificies if CCL operatores and qualifiers should be
-          compared with case sensitivity or not. Specify 0 for
-          case sensitive; 1 for case insensitive.</entry>
-         <entry><literal>0</literal></entry>
+         <entry>Specifies if CCL operators and qualifiers should be
+          compared with case sensitivity or not. Specify 1 for
+          case sensitive; 0 for case insensitive.</entry>
+         <entry><literal>1</literal></entry>
         </row>
 
         <row>
       To parse a simple string with a FIND query use the function
      </para>
      <screen>
-struct ccl_rpn_node *ccl_find_str (CCL_bibset bibset, const char *str,
-                                   int *error, int *pos);
+struct ccl_rpn_node *ccl_find_str(CCL_bibset bibset, const char *str,
+                                  int *error, int *pos);
      </screen>
      <para>
       which takes the CCL profile (<literal>bibset</literal>) and query
@@ -966,7 +993,7 @@ struct ccl_rpn_node *ccl_find_str (CCL_bibset bibset, const char *str,
     </para>
     <tip>
      <para>
-      If you are new to CQL, read the 
+      If you are new to CQL, read the
       <ulink url="&url.cql.intro;">Gentle Introduction</ulink>.
      </para>
     </tip>
@@ -1049,7 +1076,7 @@ int cql_parser_stdio(CQL_parser cp, FILE *f);
       uses a <literal>FILE</literal> handle which is opened for reading.
      </para>
     </sect3>
-    
+
     <sect3 id="cql.tree"><title>CQL tree</title>
      <para>
       The the query string is valid, the CQL parser
@@ -1064,12 +1091,13 @@ struct cql_node *cql_parser_result(CQL_parser cp);
       a pointer to the root node of the resulting tree.
      </para>
      <para>
-      Each node in a CQL tree is represented by a 
+      Each node in a CQL tree is represented by a
       <literal>struct cql_node</literal>.
       It is defined as follows:
       <synopsis>
 #define CQL_NODE_ST 1
 #define CQL_NODE_BOOL 2
+#define CQL_NODE_SORT 3
 struct cql_node {
     int which;
     union {
@@ -1087,10 +1115,17 @@ struct cql_node {
             struct cql_node *right;
             struct cql_node *modifiers;
         } boolean;
+        struct {
+            char *index;
+            struct cql_node *next;
+            struct cql_node *modifiers;
+            struct cql_node *search;
+        } sort;
     } u;
 };
       </synopsis>
-      There are two node types: search term (ST) and boolean (BOOL).
+      There are three node types: search term (ST), boolean (BOOL)
+      and sortby (SORT).
       A modifier is treated as a search term too.
      </para>
      <para>
@@ -1135,8 +1170,8 @@ struct cql_node {
      </para>
 
      <para>
-      The boolean node represents both <literal>and</literal>,
-      <literal>or</literal>, not as well as
+      The boolean node represents <literal>and</literal>,
+      <literal>or</literal>, <literal>not</literal> +
       proximity.
       <itemizedlist>
        <listitem>
@@ -1153,12 +1188,16 @@ struct cql_node {
       </itemizedlist>
      </para>
 
+     <para>
+      The sort node represents both the SORTBY clause.
+     </para>
+
     </sect3>
     <sect3 id="cql.to.pqf"><title>CQL to PQF conversion</title>
      <para>
       Conversion to PQF (and Z39.50 RPN) is tricky by the fact
       that the resulting RPN depends on the Z39.50 target
-      capabilities (combinations of supported attributes). 
+      capabilities (combinations of supported attributes).
       In addition, the CQL and SRU operates on index prefixes
       (URI or strings), whereas the RPN uses Object Identifiers
       for attribute sets.
@@ -1176,7 +1215,7 @@ void cql_transform_close(cql_transform_t ct);
       either an already open FILE or from a filename respectively.
      </para>
      <para>
-      The handle is destroyed by <function>cql_transform_close</function> 
+      The handle is destroyed by <function>cql_transform_close</function>
       in which case no further reference of the handle is allowed.
      </para>
      <para>
@@ -1186,7 +1225,7 @@ void cql_transform_close(cql_transform_t ct);
 int cql_transform_buf(cql_transform_t ct,
                       struct cql_node *cn, char *out, int max);
       </synopsis>
-      This function converts the CQL tree <literal>cn</literal> 
+      This function converts the CQL tree <literal>cn</literal>
       using handle <literal>ct</literal>.
       For the resulting PQF, you supply a buffer <literal>out</literal>
       which must be able to hold at at least <literal>max</literal>
@@ -1239,7 +1278,7 @@ int cql_transform_FILE(cql_transform_t ct,
     <sect3 id="cql.to.rpn">
      <title>Specification of CQL to RPN mappings</title>
      <para>
-      The file supplied to functions 
+      The file supplied to functions
       <function>cql_transform_open_FILE</function>,
       <function>cql_transform_open_fname</function> follows
       a structure found in many Unix utilities.
@@ -1277,7 +1316,7 @@ int cql_transform_FILE(cql_transform_t ct,
         </term>
         <listitem>
          <para>
-          This pattern is invoked when a CQL index, such as 
+          This pattern is invoked when a CQL index, such as
           dc.title is converted. <replaceable>set</replaceable>
           and <replaceable>name</replaceable> are the context set and index
           name respectively.
@@ -1291,7 +1330,7 @@ int cql_transform_FILE(cql_transform_t ct,
           If this pattern is not defined, the mapping will fail.
          </para>
          <para>
-          The pattern, 
+          The pattern,
           <literal>index.</literal><replaceable>set</replaceable><literal>.*</literal>
           is used when no other index pattern is matched.
         </para>
@@ -1356,7 +1395,7 @@ int cql_transform_FILE(cql_transform_t ct,
          <para>
           This pattern specifies how a CQL structure is mapped to RPN.
           Note that this CQL pattern is somewhat to similar to
-          CQL pattern <literal>relation</literal>. 
+          CQL pattern <literal>relation</literal>.
           The <replaceable>type</replaceable> is a CQL relation.
          </para>
          <para>
@@ -1391,7 +1430,7 @@ int cql_transform_FILE(cql_transform_t ct,
         <listitem>
          <para>
           This specification defines a CQL context set for a given prefix.
-          The value on the right hand side is the URI for the set - 
+          The value on the right hand side is the URI for the set -
           <emphasis>not</emphasis> RPN. All prefixes used in
           index patterns must be defined this way.
          </para>
@@ -1424,7 +1463,7 @@ int cql_transform_FILE(cql_transform_t ct,
        index.cql.serverChoice = 1=1016
        index.dc.title         = 1=4
        index.dc.subject       = 1=21
-  
+
        relation.<             = 2=1
        relation.eq            = 2=3
        relation.scr           = 2=3
@@ -1519,7 +1558,7 @@ int cql_transform_FILE(cql_transform_t ct,
       containing XCQL).
       <synopsis>
 int cql_to_xml_buf(struct cql_node *cn, char *out, int max);
-void cql_to_xml(struct cql_node *cn, 
+void cql_to_xml(struct cql_node *cn,
                 void (*pr)(const char *buf, void *client_data),
                 void *client_data);
 void cql_to_xml_stdio(struct cql_node *cn, FILE *f);
@@ -1535,33 +1574,57 @@ void cql_to_xml_stdio(struct cql_node *cn, FILE *f);
       a file.
      </para>
     </sect3>
+    <sect3 id="rpn.to.cql">
+     <title>PQF to CQL conversion</title>
+     <para>
+      Conversion from PQF to CQL is offered by the two functions shown
+      below. The former uses a generic stream for result. The latter
+      puts result in a WRBUF (string container).
+     <synopsis>
+#include &lt;yaz/rpn2cql.h>
+
+int cql_transform_rpn2cql_stream(cql_transform_t ct,
+                                 void (*pr)(const char *buf, void *client_data),
+                                 void *client_data,
+                                 Z_RPNQuery *q);
+
+int cql_transform_rpn2cql_wrbuf(cql_transform_t ct,
+                                WRBUF w,
+                                Z_RPNQuery *q);
+      </synopsis>
+      The configuration is the same as used in CQL to PQF conversions.
+     </para>
+    </sect3>
    </sect2>
   </sect1>
   <sect1 id="tools.oid"><title>Object Identifiers</title>
 
    <para>
     The basic YAZ representation of an OID is an array of integers,
-    terminated with the value -1. There is a <literal>typedef</literal>
-    of this integer to <literal>Odr_oid</literal> but this is not consistenly
-    used everywhere.
+    terminated with the value -1. This integer is of type
+    <literal>Odr_oid</literal>.
+   </para>
+   <para>
+    Fundamental OID operations and the type <literal>Odr_oid</literal>
+    are defined in <filename>yaz/oid_util.h</filename>.
    </para>
    <para>
-    An OID can either be declared as a automatic variable or we can
-    allocated using the ODR/NMEM memory utilities. It's
+    An OID can either be declared as a automatic variable or it can
+    allocated using the memory utilities or ODR/NMEM. It's
     guaranteed that an OID can fit in <literal>OID_SIZE</literal> integers.
    </para>
    <example id="tools.oid.bib1.1"><title>Create OID on stack</title>
     <para>
      We can create an OID for the Bib-1 attribute set with:
      <screen>
-      int bib1[OID_SIZE];
-      myoid[0] = 1;
-      myoid[1] = 2;
-      myoid[2] = 840;
-      myoid[3] = 10003;
-      myoid[4] = 3;
-      myoid[5] = 1;
-      myoid[6] = -1;
+      Odr_oid bib1[OID_SIZE];
+      bib1[0] = 1;
+      bib1[1] = 2;
+      bib1[2] = 840;
+      bib1[3] = 10003;
+      bib1[4] = 3;
+      bib1[5] = 1;
+      bib1[6] = -1;
      </screen>
     </para>
    </example>
@@ -1569,14 +1632,15 @@ void cql_to_xml_stdio(struct cql_node *cn, FILE *f);
     And OID may also be filled from a string-based representation using
     dots (.). This is achieved by function
     <screen>
-     int oid_dotstring_to_oid(const char *name, int *oid);
+     int oid_dotstring_to_oid(const char *name, Odr_oid *oid);
     </screen>
+    This functions returns 0 if name could be converted; -1 otherwise.
    </para>
    <example id="tools.oid.bib1.2"><title>Using oid_oiddotstring_to_oid</title>
     <para>
-     We can create the Bib-1 attribute set OID easier with:
+     We can fill the Bib-1 attribute set OID easier with:
      <screen>
-      int bib1[OID_SIZE];
+      Odr_oid bib1[OID_SIZE];
       oid_oiddotstring_to_oid("1.2.840.10003.3.1", bib1);
      </screen>
    </para>
@@ -1604,7 +1668,7 @@ void cql_to_xml_stdio(struct cql_node *cn, FILE *f);
    <para>
     The function
     <screen>
-     char *oid_oid_to_dotstring(const int *oid, char *oidbuf)
+     char *oid_oid_to_dotstring(const Odr_oid *oid, char *oidbuf)
     </screen>
     does the reverse of <function>oid_oiddotstring_to_oid</function>. It
     converts an OID to the string-based representation using dots.
@@ -1620,17 +1684,17 @@ void cql_to_xml_stdio(struct cql_node *cn, FILE *f);
      Odr_oid *odr_oiddup(ODR odr, const Odr_oid *o);
     </screen>
    </para>
-   
+
    <para>
     OIDs can be compared with <function>oid_oidcmp</function> which returns
     zero if the two OIDs provided are identical; non-zero otherwise.
    </para>
+
    <sect2 id="tools.oid.database"><title>OID database</title>
     <para>
      From YAZ version 3 and later, the oident system has been replaced
      by an OID database. OID database is a misnomer .. the old odient
-     was a database system too.
+     system was also a database.
     </para>
     <para>
      The OID database is really just a map between named Object Identifiers
@@ -1638,21 +1702,21 @@ void cql_to_xml_stdio(struct cql_node *cn, FILE *f);
      convert from string to OID or other way around.
     </para>
     <para>
-     Unfortunately, whenever we supply a string we must also specify the 
+     Unfortunately, whenever we supply a string we must also specify the
      <emphasis>OID class</emphasis>. The class is necessary because some
      strings correspond to multiple OIDs. An example of such a string is
-     <literal>Bib-1</literal> which may either be an attribute-set 
+     <literal>Bib-1</literal> which may either be an attribute-set
      or a diagnostic-set.
     </para>
     <para>
-     Applications using the YAZ database should include 
-     <filename>yaz/yaz_db.h</filename>.
+     Applications using the YAZ database should include
+     <filename>yaz/oid_db.h</filename>.
     </para>
     <para>
      A YAZ database handle is of type <literal>yaz_oid_db_t</literal>.
      Actually that's a pointer. You need not think deal with that.
      YAZ has a built-in database which can be considered "constant" for
-     most purposes. 
+     most purposes.
      We can get hold that by using function <function>yaz_oid_std</function>.
     </para>
     <para>
@@ -1671,7 +1735,7 @@ void cql_to_xml_stdio(struct cql_node *cn, FILE *f);
       We can create an OID for the Bib-1 attribute set on the ODR stream
       odr with:
      <screen>
-        Odr_oid *bib1 = 
+        Odr_oid *bib1 =
          yaz_string_to_oid_odr(yaz_oid_std(), CLASS_ATTSET, "Bib-1", odr);
       </screen>
       This is more complex than using <function>odr_getoidbystr</function>.
@@ -1679,15 +1743,21 @@ void cql_to_xml_stdio(struct cql_node *cn, FILE *f);
       string (here Bib-1) is supplied by a user or configuration.
      </para>
     </example>
-     
+
+   </sect2>
+   <sect2 id="tools.oid.std"><title>Standard OIDs</title>
+
     <para>
      All the object identifers in the standard OID database as returned
      by <function>yaz_oid_std</function> can referenced directly in a
-     program. Each constant OID is prefixed with <literal>yaz_oid_</literal> -
+     program as a constant OID.
+     Each constant OID is prefixed with <literal>yaz_oid_</literal> -
      followed by OID class (lowercase) - then by OID name (normalized and
      lowercase).
     </para>
     <para>
+     See <xref linkend="list-oids"/> for list of all object identifiers
+     built into YAZ.
      These are declared in <filename>yaz/oid_std.h</filename> but are
      included by <filename>yaz/oid_db.h</filename> as well.
     </para>
@@ -1702,265 +1772,6 @@ void cql_to_xml_stdio(struct cql_node *cn, FILE *f);
      </para>
     </example>
    </sect2>
-
-   <sect2 id="tools.oid.oident"><title>OID oident</title>
-
-   <note>
-    <para>
-     The oident utility has been removed from YAZ version 3. This
-     sub section only applies to YAZ version 2.
-    </para>
-   </note>
-
-   <para>
-    The OID module provides a higher-level representation of the
-    family of object identifiers which describe the Z39.50 protocol and its
-    related objects. The definition of the module interface is given in
-    the <filename>oid.h</filename> file.
-   </para>
-
-   <para>
-    The interface is mainly based on the <literal>oident</literal> structure.
-    The definition of this structure looks like this:
-   </para>
-
-   <screen>
-typedef struct oident
-{
-    oid_proto proto;
-    oid_class oclass;
-    oid_value value;
-    int oidsuffix[OID_SIZE];
-    char *desc;
-} oident;
-   </screen>
-
-   <para>
-    The proto field takes one of the values
-   </para>
-
-   <screen>
-    PROTO_Z3950
-    PROTO_GENERAL
-   </screen>
-
-   <para>
-    Use <literal>PROTO_Z3950</literal> for Z39.50 Object Identifers,
-    <literal>PROTO_GENERAL</literal> for other types (such as
-    those associated with ILL).
-   </para>
-   <para>
-
-    The oclass field takes one of the values
-   </para>
-
-   <screen>
-    CLASS_APPCTX
-    CLASS_ABSYN
-    CLASS_ATTSET
-    CLASS_TRANSYN
-    CLASS_DIAGSET
-    CLASS_RECSYN
-    CLASS_RESFORM
-    CLASS_ACCFORM
-    CLASS_EXTSERV
-    CLASS_USERINFO
-    CLASS_ELEMSPEC
-    CLASS_VARSET
-    CLASS_SCHEMA
-    CLASS_TAGSET
-    CLASS_GENERAL
-   </screen>
-
-   <para>
-    corresponding to the OID classes defined by the Z39.50 standard.
-
-    Finally, the value field takes one of the values
-   </para>
-
-   <screen>
-    VAL_APDU
-    VAL_BER
-    VAL_BASIC_CTX
-    VAL_BIB1
-    VAL_EXP1
-    VAL_EXT1
-    VAL_CCL1
-    VAL_GILS
-    VAL_WAIS
-    VAL_STAS
-    VAL_DIAG1
-    VAL_ISO2709
-    VAL_UNIMARC
-    VAL_INTERMARC
-    VAL_CCF
-    VAL_USMARC
-    VAL_UKMARC
-    VAL_NORMARC
-    VAL_LIBRISMARC
-    VAL_DANMARC
-    VAL_FINMARC
-    VAL_MAB
-    VAL_CANMARC
-    VAL_SBN
-    VAL_PICAMARC
-    VAL_AUSMARC
-    VAL_IBERMARC
-    VAL_EXPLAIN
-    VAL_SUTRS
-    VAL_OPAC
-    VAL_SUMMARY
-    VAL_GRS0
-    VAL_GRS1
-    VAL_EXTENDED
-    VAL_RESOURCE1
-    VAL_RESOURCE2
-    VAL_PROMPT1
-    VAL_DES1
-    VAL_KRB1
-    VAL_PRESSET
-    VAL_PQUERY
-    VAL_PCQUERY
-    VAL_ITEMORDER
-    VAL_DBUPDATE
-    VAL_EXPORTSPEC
-    VAL_EXPORTINV
-    VAL_NONE
-    VAL_SETM
-    VAL_SETG
-    VAL_VAR1
-    VAL_ESPEC1
-   </screen>
-
-   <para>
-    again, corresponding to the specific OIDs defined by the standard.
-    Refer to the
-    <ulink url="&url.z39.50.oids;">
-     Registry of Z39.50 Object Identifiers</ulink> for the
-     whole list.
-   </para>
-
-   <para>
-    The desc field contains a brief, mnemonic name for the OID in question.
-   </para>
-
-   <para>
-    The function
-   </para>
-
-   <screen>
-    struct oident *oid_getentbyoid(int *o);
-   </screen>
-
-   <para>
-    takes as argument an OID, and returns a pointer to a static area
-    containing an <literal>oident</literal> structure. You typically use
-    this function when you receive a PDU containing an OID, and you wish
-    to branch out depending on the specific OID value.
-   </para>
-
-   <para>
-    The function
-   </para>
-
-   <screen>
-    int *oid_ent_to_oid(struct oident *ent, int *dst);
-   </screen>
-
-   <para>
-    Takes as argument an <literal>oident</literal> structure - in which
-    the <literal>proto</literal>, <literal>oclass</literal>/, and
-    <literal>value</literal> fields are assumed to be set correctly -
-    and returns a pointer to a the buffer as given by <literal>dst</literal>
-    containing the base
-    representation of the corresponding OID. The function returns
-    NULL and the array dst is unchanged if a mapping couldn't place.
-    The array <literal>dst</literal> should be at least of size
-    <literal>OID_SIZE</literal>.
-   </para>
-   <para>
-
-    The <function>oid_ent_to_oid()</function> function can be used whenever
-    you need to prepare a PDU containing one or more OIDs. The separation of
-    the <literal>protocol</literal> element from the remainder of the
-    OID-description makes it simple to write applications that can
-    communicate with either Z39.50 or OSI SR-based applications.
-   </para>
-
-   <para>
-    The function
-   </para>
-
-   <screen>
-    oid_value oid_getvalbyname(const char *name);
-   </screen>
-
-   <para>
-    takes as argument a mnemonic OID name, and returns the
-    <literal>/value</literal> field of the first entry in the database that 
-    contains the given name in its <literal>desc</literal> field.
-   </para>
-
-   <para>
-    Three utility functions are provided for translating OIDs'
-    symbolic names (e.g. <literal>Usmarc</literal> into OID structures
-    (int arrays) and strings containing the OID in dotted notation
-    (e.g. <literal>1.2.840.10003.9.5.1</literal>).  They are:
-   </para>
-
-   <screen>
-    int *oid_name_to_oid(oid_class oclass, const char *name, int *oid);
-    char *oid_to_dotstring(const int *oid, char *oidbuf);
-    char *oid_name_to_dotstring(oid_class oclass, const char *name, char *oidbuf);
-   </screen>
-
-   <para>
-    <literal>oid_name_to_oid()</literal>
-     translates the specified symbolic <literal>name</literal>,
-     interpreted as being of class <literal>oclass</literal>.  (The
-     class must be specified as many symbolic names exist within
-     multiple classes - for example, <literal>Zthes</literal> is the
-     symbolic name of an attribute set, a schema and a tag-set.)  The
-     sequence of integers representing the OID is written into the
-     area <literal>oid</literal> provided by the caller; it is the
-     caller's responsibility to ensure that this area is large enough
-     to contain the translated OID.  As a convenience, the address of
-     the buffer (i.e. the value of <literal>oid</literal>) is
-     returned.
-   </para>
-   <para>
-    <literal>oid_to_dotstring()</literal>
-    Translates the int-array <literal>oid</literal> into a dotted
-    string which is written into the area <literal>oidbuf</literal>
-    supplied by the caller; it is the caller's responsibility to
-    ensure that this area is large enough.  The address of the buffer
-    is returned.
-   </para>
-   <para>
-    <literal>oid_name_to_dotstring()</literal>
-    combines the previous two functions to derive a dotted string
-    representing the OID specified by <literal>oclass</literal> and
-    <literal>name</literal>, writing it into the buffer passed as
-    <literal>oidbuf</literal> and returning its address.
-   </para>
-
-   <note>
-    <para>
-     The OID module has been criticized - and perhaps rightly so
-     - for needlessly abstracting the
-     representation of OIDs. Other toolkits use a simple
-     string-representation of OIDs with good results. In practice, we have
-     found the interface comfortable and quick to work with, and it is a
-     simple matter (for what it's worth) to create applications compatible
-     with both ISO SR and Z39.50. Finally, the use of the
-     <literal>/oident</literal> database is by no means mandatory.
-     You can easily create your own system for representing OIDs, as long
-     as it is compatible with the low-level integer-array representation
-     of the ODR module.
-    </para>
-   </note>
-
-   </sect2>
   </sect1>
   <sect1 id="tools.nmem"><title>Nibble Memory</title>
 
@@ -1986,9 +1797,9 @@ typedef struct oident
    <screen>
     NMEM nmem_create(void);
     void nmem_destroy(NMEM n);
-    void *nmem_malloc(NMEM n, int size);
+    void *nmem_malloc(NMEM n, size_t size);
     void nmem_reset(NMEM n);
-    int nmem_total(NMEM n);
+    size_t nmem_total(NMEM n);
     void nmem_init(void);
     void nmem_exit(void);
    </screen>
@@ -2016,16 +1827,16 @@ typedef struct oident
     <emphasis>not</emphasis> call <function>nmem_init</function> or
     <function>nmem_exit</function> unless you're absolute sure what
     you're doing. Note that in previous &yaz; versions you'd have to call
-    <function>nmem_init</function> yourself. 
+    <function>nmem_init</function> yourself.
    </para>
 
   </sect1>
 
   <sect1 id="tools.log"><title>Log</title>
   <para>
-   &yaz; has evolved a fairly complex log system which should be useful both 
+   &yaz; has evolved a fairly complex log system which should be useful both
    for debugging &yaz; itself, debugging applications that use &yaz;, and for
-   production use of those applications.  
+   production use of those applications.
   </para>
   <para>
    The log functions are declared in header <filename>yaz/log.h</filename>
@@ -2079,7 +1890,7 @@ typedef struct oident
    logged. This string should be a comma-separated list of log level names,
    and can contain both hard-coded names and dynamic ones. The log level
    calculation starts with <literal>YLOG_DEFAULT_LEVEL</literal> and adds a bit
-   for each word it meets, unless the word starts with a '-', in which case it 
+   for each word it meets, unless the word starts with a '-', in which case it
    clears the bit. If the string <literal>'none'</literal> is found,
    all bits are cleared. Typically this string comes from the command-line,
    often identified by <literal>-v</literal>. The
@@ -2088,15 +1899,15 @@ typedef struct oident
   </para>
 
   <para>
-   Each module should check what log bits it should be used, by calling 
+   Each module should check what log bits it should be used, by calling
    <function>yaz_log_module_level</function> with a suitable name for the
    module. The name is cleared from a preceding path and an extension, if any,
    so it is quite possible to use <literal>__FILE__</literal> for it. If the
    name has been passed to <function>yaz_log_mask_str</function>, the routine
    returns a non-zero bitmask, which should then be used in consequent calls
    to yaz_log. (It can also be tested, so as to avoid unnecessary calls to
-   yaz_log, in time-critical places, or when the log entry would take time 
-   to construct.) 
+   yaz_log, in time-critical places, or when the log entry would take time
+   to construct.)
   </para>
 
   <para>
@@ -2158,24 +1969,24 @@ typedef struct oident
   <para>
    The log system is almost independent of the rest of &yaz;, the only
    important dependence is of <filename>nmem</filename>, and that only for
-   using the semaphore definition there. 
+   using the semaphore definition there.
   </para>
 
   <para>
    The dynamic log levels and log rotation were introduced in &yaz; 2.0.28. At
    the same time, the log bit names were changed from
-   <literal>LOG_something</literal> to <literal>YLOG_something</literal>, 
+   <literal>LOG_something</literal> to <literal>YLOG_something</literal>,
    to avoid collision with <filename>syslog.h</filename>.
   </para>
 
   </sect1>
-  
+
   <sect1 id="marc"><title>MARC</title>
-   
+
    <para>
-    YAZ provides a fast utility that decodes MARC records and
-    encodes to a varity of output formats. The MARC records must
-    be encoded in ISO2709.
+    YAZ provides a fast utility for working with MARC records.
+    Early versions of the MARC utility only allowed decoding of ISO2709.
+    Today the utility may both encode - and decode to a varity of formats.
    </para>
    <synopsis><![CDATA[
     #include <yaz/marcdisp.h>
@@ -2193,6 +2004,8 @@ typedef struct oident
     #define YAZ_MARC_MARCXML   3
     #define YAZ_MARC_ISO2709   4
     #define YAZ_MARC_XCHANGE   5
+    #define YAZ_MARC_CHECK     6
+    #define YAZ_MARC_TURBOMARC 7
 
     /* supply iconv handle for character set conversion .. */
     void yaz_marc_iconv(yaz_marc_t mt, yaz_iconv_t cd);
@@ -2202,15 +2015,22 @@ typedef struct oident
 
     /* decode MARC in buf of size bsize. Returns >0 on success; <=0 on failure.
     On success, result in *result with size *rsize. */
-    int yaz_marc_decode_buf (yaz_marc_t mt, const char *buf, int bsize,
-                             char **result, int *rsize);
+    int yaz_marc_decode_buf(yaz_marc_t mt, const char *buf, int bsize,
+                            const char **result, size_t *rsize);
 
     /* decode MARC in buf of size bsize. Returns >0 on success; <=0 on failure.
        On success, result in WRBUF */
-    int yaz_marc_decode_wrbuf (yaz_marc_t mt, const char *buf,
-                               int bsize, WRBUF wrbuf);
+    int yaz_marc_decode_wrbuf(yaz_marc_t mt, const char *buf,
+                              int bsize, WRBUF wrbuf);
 ]]>
    </synopsis>
+   <note>
+    <para>
+     The synopsis is just a basic subset of all functionality. Refer
+     to the actual header file <filename>marcdisp.h</filename> for
+     details.
+    </para>
+   </note>
    <para>
     A MARC conversion handle must be created by using
     <function>yaz_marc_create</function> and destroyed
@@ -2235,7 +2055,7 @@ typedef struct oident
       <term>YAZ_MARC_MARCXML</term>
       <listitem>
        <para>
-       The resulting record is converted to MARCXML.
+       <ulink url="&url.marcxml;">MARCXML</ulink>.
        </para>
       </listitem>
      </varlistentry>
@@ -2244,14 +2064,45 @@ typedef struct oident
       <term>YAZ_MARC_ISO2709</term>
       <listitem>
        <para>
-       The resulting record is converted to ISO2709 (MARC).
+       ISO2709 (sometimes just referred to as "MARC").
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
+      <term>YAZ_MARC_XCHANGE</term>
+      <listitem>
+       <para>
+       <ulink url="&url.marcxchange;">MarcXchange</ulink>.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
+      <term>YAZ_MARC_CHECK</term>
+      <listitem>
+       <para>
+       Pseudo format for validation only. Does not generate
+       any real output except diagnostics.
+       </para>
+      </listitem>
+     </varlistentry>
+
+     <varlistentry>
+      <term>YAZ_MARC_TURBOMARC</term>
+      <listitem>
+       <para>
+       XML format with same semantics as MARCXML but more compact
+       and geared towards fast processing with XSLT. Refer to
+       <xref linkend="tools.turbomarc"/> for more information.
        </para>
       </listitem>
      </varlistentry>
+
     </variablelist>
    </para>
    <para>
-    The actual conversion functions are 
+    The actual conversion functions are
     <function>yaz_marc_decode_buf</function> and
     <function>yaz_marc_decode_wrbuf</function> which decodes and encodes
     a MARC record. The former function operates on simple buffers, the
@@ -2261,13 +2112,13 @@ typedef struct oident
    <example id="example.marc.display">
     <title>Display of MARC record</title>
     <para>
-     The followint program snippet illustrates how the MARC API may
+     The following program snippet illustrates how the MARC API may
      be used to convert a MARC record to the line-by-line format:
      <programlisting><![CDATA[
       void print_marc(const char *marc_buf, int marc_buf_size)
       {
          char *result;      /* for result buf */
-         int result_len;    /* for size of result */
+         size_t result_len;    /* for size of result */
          yaz_marc_t mt = yaz_marc_create();
          yaz_marc_xml(mt, YAZ_MARC_LINE);
          yaz_marc_decode_buf(mt, marc_buf, marc_buf_size,
@@ -2279,6 +2130,71 @@ typedef struct oident
       </programlisting>
     </para>
    </example>
+   <sect2 id="tools.turbomarc">
+    <title>TurboMARC</title>
+    <para>
+     TurboMARC is yet another XML encoding of a MARC record. The format
+     was designed for fast processing with XSLT.
+    </para>
+    <para>
+     Applications like
+     Pazpar2 uses XSLT to convert an XML encoded MARC record to an internal
+     representation. This conversion mostly check the tag of a MARC field
+     to determine the basic rules in the conversion. This check is
+     costly when that is tag is encoded as an attribute in MARCXML.
+     By having the tag value as the element instead, makes processing
+     many times faster (at least for Libxslt).
+    </para>
+    <para>
+     TurboMARC is encoded as follows:
+     <itemizedlist>
+      <listitem><para>
+       Record elements is part of namespace
+       "<literal>http://www.indexdata.com/turbomarc</literal>".
+       </para></listitem>
+      <listitem><para>
+       A record is enclosed in element <literal>r</literal>.
+       </para></listitem>
+      <listitem><para>
+       A collection of records is enclosed in element
+       <literal>collection</literal>.
+       </para></listitem>
+      <listitem><para>
+       The leader is encoded as element <literal>l</literal> with the
+       leader content as its (text) value.
+       </para></listitem>
+      <listitem><para>
+       A control field is encoded as element <literal>c</literal> concatenated
+       with the tag value of the control field if the tag value
+       matches the regular expression <literal>[a-zA-Z0-9]*</literal>.
+       If the tag value do not match the regular expression
+       <literal>[a-zA-Z0-9]*</literal> the control field is encoded
+       as element <literal>c</literal> and attribute <literal>code</literal>
+       will hold the tag value.
+       This rule ensure that in the rare cases where a tag value might
+       result in a non-wellformed XML YAZ encode it as a coded attribute
+       (as in MARCXML).
+       </para>
+       <para>
+       The control field content is the the text value of this element.
+       Indicators are encoded as attribute names
+       <literal>i1</literal>, <literal>i2</literal>, etc.. and
+       corresponding values for each indicator.
+       </para></listitem>
+      <listitem><para>
+       A data field is encoded as element <literal>d</literal> concatenated
+       with the tag value of the data field or using the attribute
+       <literal>code</literal> as described in the rules for control fields.
+       The children of the data field element is subfield elements.
+       Each subfield element is encoded as <literal>s</literal>
+       concatenated with the sub field code.
+       The text of the subfield element is the contents of the subfield.
+       Indicators are encoded as attributes for the data field element similar
+       to the encoding for control fields.
+       </para></listitem>
+     </itemizedlist>
+    </para>
+   </sect2>
   </sect1>
 
   <sect1 id="tools.retrieval">
@@ -2287,7 +2203,7 @@ typedef struct oident
     YAZ version 2.1.20 or later includes a Retrieval facility tool
     which allows a SRU/Z39.50 to describe itself and perform record
     conversions. The idea is the following:
-    
+
     <itemizedlist>
      <listitem>
       <para>
@@ -2335,13 +2251,13 @@ typedef struct oident
    <sect2 id="tools.retrieval.format">
     <title>Retrieval XML format</title>
     <para>
-     All elements should be covered by namespace 
+     All elements should be covered by namespace
      <literal>http://indexdata.com/yaz</literal> .
      The root element node must be <literal>retrievalinfo</literal>.
     </para>
     <para>
      The <literal>retrievalinfo</literal> must include one or
-     more <literal>retrieval</literal> elements. Each 
+     more <literal>retrieval</literal> elements. Each
     <literal>retrieval</literal> defines specific combination of
      syntax, name and identifier supported by this retrieval service.
     </para>
@@ -2363,7 +2279,10 @@ typedef struct oident
         <para>
          Defines the name of the retrieval format. This can be
          any string. For SRU, the value, is equivalent to schema (short-hand);
-         for Z39.50 it's equivalent to simple element set name. 
+         for Z39.50 it's equivalent to simple element set name.
+         For YAZ 3.0.24 and later this name may be specified as a glob
+         expression with operators
+         <literal>*</literal> and <literal>?</literal>.
         </para>
        </listitem>
       </varlistentry>
@@ -2379,7 +2298,7 @@ typedef struct oident
      </variablelist>
     </para>
     <para>
-     The <literal>retrieval</literal> may include one 
+     The <literal>retrieval</literal> may include one
      <literal>backend</literal> element. If a <literal>backend</literal>
      element is given, it specifies how the records are retrieved by
      some backend and how the records are converted from the backend to
@@ -2400,16 +2319,16 @@ typedef struct oident
       <varlistentry><term><literal>marc</literal></term>
        <listitem>
         <para>
-         The <literal>marc</literal> element specifies a conversion 
-         to - and from ISO2709 encoded MARC and 
-         <ulink url="&url.marcxml;">&marcxml;</ulink>/MarcXchange.
+         The <literal>marc</literal> element specifies a conversion
+         to - and from ISO2709 encoded MARC and
+         <ulink url="&url.marcxml;">&acro.marcxml;</ulink>/MarcXchange.
          The following attributes may be specified:
 
          <variablelist>
           <varlistentry><term><literal>inputformat</literal> (REQUIRED)</term>
            <listitem>
             <para>
-             Format of input. Supported values are 
+             Format of input. Supported values are
             <literal>marc</literal> (for ISO2709); and <literal>xml</literal>
              for MARCXML/MarcXchange.
             </para>
@@ -2419,8 +2338,8 @@ typedef struct oident
           <varlistentry><term><literal>outputformat</literal> (REQUIRED)</term>
            <listitem>
             <para>
-             Format of output. Supported values are 
-            <literal>line</literal> (MARC line format); 
+             Format of output. Supported values are
+            <literal>line</literal> (MARC line format);
             <literal>marcxml</literal> (for MARCXML),
             <literal>marc</literal> (ISO2709),
             <literal>marcxhcange</literal> (for MarcXchange).
@@ -2456,7 +2375,7 @@ typedef struct oident
        <listitem>
         <para>
          The <literal>xslt</literal> element specifies a conversion
-         via &xslt;. The following attributes may be specified:
+         via &acro.xslt;. The following attributes may be specified:
 
          <variablelist>
           <varlistentry><term><literal>stylesheet</literal> (REQUIRED)</term>
@@ -2531,19 +2450,143 @@ typedef struct oident
       </itemizedlist>
      </para>
     </example>
+
+    <example id="tools.retrieval.marcxml">
+     <title>MARCXML backend</title>
+     <para>
+      SRW/SRU and Solr backends returns records in XML.
+      If they return MARCXML or MarcXchange, the retrieval module
+      can convert those into ISO2709 formats, most commonly USMARC
+      (AKA MARC21).
+      In this example, the backend returns MARCXML for schema="marcxml".
+     </para>
+     <programlisting><![CDATA[
+     <retrievalinfo>
+       <retrieval syntax="usmarc">
+         <backend syntax="xml" name="marcxml">
+          <marc inputformat="xml" outputformat="marc"
+                outputcharset="marc-8"/>
+        </backend>
+       </retrieval>
+       <retrieval syntax="xml" name="marcxml"
+                 identifier="info:srw/schema/1/marcxml-v1.1"/>
+       <retrieval syntax="xml" name="dc">
+         <backend syntax="xml" name="marcxml">
+           <xslt stylesheet="MARC21slim2DC.xsl"/>
+        </backend>
+       </retrieval>
+     </retrievalinfo>
+]]>
+     </programlisting>
+     <para>
+      This means that our frontend supports:
+      <itemizedlist>
+       <listitem>
+        <para>
+         MARC21 records (any element set name) in MARC-8 encoding.
+        </para>
+       </listitem>
+       <listitem>
+        <para>
+         MARCXML records for element-set=marcxml
+        </para>
+       </listitem>
+       <listitem>
+        <para>
+         Dublin core records for element-set=dc.
+        </para>
+       </listitem>
+      </itemizedlist>
+     </para>
+    </example>
+
    </sect2>
    <sect2 id="tools.retrieval.api">
     <title>API</title>
     <para>
      It should be easy to use the retrieval systems from applications. Refer
      to the headers
-     <filename>yaz/retrieval.h</filename> and 
+     <filename>yaz/retrieval.h</filename> and
      <filename>yaz/record_conv.h</filename>.
     </para>
    </sect2>
   </sect1>
+  <sect1><title>Sorting</title>
+   <para>
+    This chapter describes sorting and how it is supported in YAZ.
+    Sorting applies to a result-set.
+    The <ulink url="http://www.loc.gov/z3950/agency/markup/05.html#3.2.7">
+     Z39.50 sorting facility
+    </ulink>
+    takes one or more input result-sets
+    and one result-set as output. The most simple case is that
+    the input-set is the same as the output-set.
+   </para>
+   <para>
+    Z39.50 sorting has a separate APDU (service) that is, thus, performed
+    following a search (two phases).
+   </para>
+   <para>
+    In SRU/Solr, however, the model is different. Here, sorting is specified
+    during the the search operation. Note, however, that SRU might
+    perform sort as separate search, by referring to an existing result-set
+    in the query (result-set reference).
+   </para>
+   <sect2><title>Using the Z39.50 sort service</title>
+    <para>
+     yaz-client and the ZOOM API supports the Z39.50 sort facility. In any
+     case the sort sequence or sort critiera is using a string notation.
+     This notation is a one-line notation suitable for being manually
+     entered or generated and allows for easy logging (one liner).
+     For the ZOOM API, the sort is specified in the call to ZOOM_query_sortby
+     function. For yaz-client the sort is performed and specified using
+     the sort and sort+ commands. For description of the sort criteria notation
+     refer to the <link linkend="sortspec">sort command</link> in the
+     yaz-client manual.
+    </para>
+    <para>
+     The ZOOM API might choose one of several sort strategies for
+     sorting. Refer to <xref linkend="zoom-sort-strategy"/>.
+    </para>
+   </sect2>
+   <sect2><title>Type-7 sort</title>
+    <para>
+     Type-7 sort is an extension to the Bib-1 based RPN query where the
+     sort specification is embedded as an Attribute-Plus-Term.
+    </para>
+    <para>
+     The objectives for introducing Type-7 sorting is that it allows
+     a client to perform sorting even if it does not implement/support
+     Z39.50 sort. Virtually all Z39.50 client software supports
+     RPN queries. It also may improve performance because the sort
+     critieria is specified along with the search query.
+    </para>
+    <para>
+     The sort is triggered by the presence of type 7 and the value of type 7
+     specifies the
+     <ulink url="http://www.loc.gov/z3950/agency/asn1.html#SortKeySpec">
+      sortRelation
+     </ulink>
+     The value for type 7 is 1 for ascending and 2 for descending.
+     For the
+     <ulink url="http://www.loc.gov/z3950/agency/asn1.html#SortElement">
+      sortElement
+     </ulink>
+     only the generic part is handled. If generic sortKey is of type
+     sortField, then attribute type 1 is present and the value is
+     sortField (InternationalString). If generic sortKey is of type
+     sortAttributes, then the attributes in list is used . generic sortKey
+     of type elementSpec is not supported.
+    </para>
+    <para>
+     The term in the sorting Attribute-Plus-Term combo should hold
+     an integer. The value is 0 for primary sorting criteria, 1 for second
+     criteria, etc.
+    </para>
+   </sect2>
+  </sect1>
  </chapter>
+
  <!-- Keep this comment at the end of the file
  Local variables:
  mode: sgml