added new generated html files to makesystem
[idzebra-moved-to-github.git] / doc / recordmodel-alvisxslt.xml
1  <chapter id="record-model-alvisxslt">
2   <!-- $Id: recordmodel-alvisxslt.xml,v 1.3 2006-02-16 12:32:31 marc Exp $ -->
3   <title>ALVIS XML Record Model and Filter Module</title>
4   
5
6   <para>
7    The record model described in this chapter applies to the fundamental,
8    structured XML
9    record type <literal>alvis</literal>, introduced in
10    <xref linkend="componentmodulesalvis"/>. The ALVIS XML record model
11    is experimental, and it's inner workings might change in future
12    releases of the Zebra Information Server.
13   </para>
14
15   <para> This filter has been developed under the 
16    <ulink url="http://www.alvis.info/">ALVIS</ulink> project funded by
17    the European Community under the "Information Society Technologies"
18    Program (2002-2006).
19   </para>
20   
21   
22   <sect1 id="record-model-alvisxslt-filter">
23    <title>ALVIS Record Filter</title>
24    <para>
25     The experimental, loadable  Alvis XML/XSLT filter module
26    <literal>mod-alvis.so</literal> is packaged in the GNU/Debian package
27     <literal>libidzebra1.4-mod-alvis</literal>.
28     It is invoked by the <filename>zebra.cfg</filename> configuration statement
29     <screen>
30      recordtype.xml: alvis.db/filter_alvis_conf.xml
31     </screen>
32     In this example on all data files with suffix 
33     <filename>*.xml</filename>, where the
34     Alvis XSLT filter configuration file is found in the
35     path <filename>db/filter_alvis_conf.xml</filename>.
36    </para>
37    <para>The Alvis XSLT filter configuration file must be
38     valid XML. It might look like this (This example is
39     used for indexing and display of OAI harvested records):
40     <screen>
41     &lt;?xml version="1.0" encoding="UTF-8"?&gt;
42       &lt;schemaInfo&gt;
43         &lt;schema name="identity" stylesheet="xsl/identity.xsl" /&gt;
44         &lt;schema name="index" identifier="http://indexdata.dk/zebra/xslt/1"
45             stylesheet="xsl/oai2index.xsl" /&gt;
46         &lt;schema name="dc" stylesheet="xsl/oai2dc.xsl" /&gt;
47         &lt;!-- use split level 2 when indexing whole OAI Record lists --&gt;
48         &lt;split level="2"/&gt;
49       &lt;/schemaInfo&gt;
50     </screen> 
51    </para>
52    <para>
53     All named stylesheets defined inside
54     <literal>schema</literal> element tags 
55     are for presentation after search, including
56     the indexing stylesheet (which is a great debugging help). The
57     names defined in the <literal>name</literal> attributes must be
58     unique, these are the literal <literal>schema</literal> or 
59     <literal>element set</literal> names used in 
60       <ulink url="http://www.loc.gov/standards/sru/srw/">SRW</ulink>,
61       <ulink url="http://www.loc.gov/standards/sru/">SRU</ulink> and
62     Z39.50 protocol queries.
63     The paths in the <literal>stylesheet</literal> attributes
64     are relative to zebras working directory, or absolute to file
65     system root.
66    </para>
67    <para>
68     The <literal>&lt;split level="2"/&gt;</literal> decides where the
69     XML Reader shall split the
70     collections of records into individual records, which then are
71     loaded into DOM, and have the indexing XSLT stylesheet applied.
72    </para>
73    <para>
74     There must be exactly one indexing XSLT stylesheet, which is
75     defined by the magic attribute  
76     <literal>identifier="http://indexdata.dk/zebra/xslt/1"</literal>.
77    </para>
78
79    <sect2 id="record-model-alvisxslt-internal">
80     <title>ALVIS Internal Record Representation</title>   
81     <para>When indexing, an XML Reader is invoked to split the input
82     files into suitable record XML pieces. Each record piece is then
83     transformed to an XML DOM structure, which is essentially the
84     record model. Only XSLT transformations can be applied during
85     index, search and retrieval. Consequently, output formats are
86     restricted to whatever XSLT can deliver from the record XML
87     structure, be it other XML formats, HTML, or plain text. In case
88     you have <literal>libxslt1</literal> running with EXSLT support,
89     you can use this functionality inside the Alvis
90     filter configuration XSLT stylesheets.
91     </para>
92    </sect2>
93
94    <sect2 id="record-model-alvisxslt-canonical">
95     <title>ALVIS Canonical Indexing Format</title>   
96     <para>The output of the indexing XSLT stylesheets must contain
97     certain elements in the magic 
98      <literal>xmlns:z="http://indexdata.dk/zebra/xslt/1"</literal>
99     namespace. The output of the XSLT indexing transformation is then
100     parsed using DOM methods, and the contained instructions are
101     performed on the <emphasis>magic elements and their
102     subtrees</emphasis>.
103     </para>
104     <para>
105     For example, the output of the command
106      <screen>  
107       xsltproc xsl/oai2index.xsl one-record.xml
108      </screen> 
109      might look like this:
110      <screen>
111       &lt;?xml version="1.0" encoding="UTF-8"?&gt;
112       &lt;z:record xmlns:z="http://indexdata.dk/zebra/xslt/1" 
113            z:id="oai:JTRS:CP-3290---Volume-I" 
114            z:rank="47896"
115            z:type="update"&gt;
116        &lt;z:index name="oai:identifier" type="0"&gt;
117                 oai:JTRS:CP-3290---Volume-I&lt;/z:index&gt;
118        &lt;z:index name="oai:datestamp" type="0"&gt;2004-07-09&lt;/z:index&gt;
119        &lt;z:index name="oai:setspec" type="0"&gt;jtrs&lt;/z:index&gt;
120        &lt;z:index name="dc:all" type="w"&gt;
121           &lt;z:index name="dc:title" type="w"&gt;Proceedings of the 4th 
122                 International Conference and Exhibition:
123                 World Congress on Superconductivity - Volume I&lt;/z:index&gt;
124           &lt;z:index name="dc:creator" type="w"&gt;Kumar Krishen and *Calvin
125                 Burnham, Editors&lt;/z:index&gt;
126        &lt;/z:index&gt;
127      &lt;/z:record&gt;
128      </screen>
129     </para>
130     <para>This means the following: From the original XML file 
131      <literal>one-record.xml</literal> (or from the XML record DOM of the
132      same form coming from a splitted input file), the indexing
133      stylesheet produces an indexing XML record, which is defined by
134      the <literal>record</literal> element in the magic namespace
135      <literal>xmlns:z="http://indexdata.dk/zebra/xslt/1"</literal>.
136      Zebra uses the content of 
137      <literal>z:id="oai:JTRS:CP-3290---Volume-I"</literal> as internal
138      record ID, and - in case static ranking is set - the content of 
139      <literal>z:rank="47896"</literal> as static rank. Following the
140      discussion in <xref linkend="administration-ranking"/>
141      we see that this records is internally ordered
142      lexicographically according to the value of the string
143      <literal>oai:JTRS:CP-3290---Volume-I47896</literal>.
144      The type of action performed during indexing is defined by
145      <literal>z:type="update"&gt;</literal>, with recognized values
146      <literal>insert</literal>, <literal>update</literal>, and 
147      <literal>delete</literal>. 
148     </para>
149     <para>In this example, the following literal indexes are constructed:
150      <screen>
151        oai:identifier
152        oai:datestamp
153        oai:setspec
154        dc:all
155        dc:title
156        dc:creator
157      </screen>
158      where the indexing type is defined in the 
159      <literal>type</literal> attribute 
160      (any value from the standard configuration
161      file <filename>default.idx</filename> will do). Finally, any 
162      <literal>text()</literal> node content recursively contained
163      inside the <literal>index</literal> will be filtered through the
164      appropriate charmap for character normalization, and will be
165      inserted in the index.
166     </para>
167     <para>
168      Specific to this example, we see that the single word
169      <literal>oai:JTRS:CP-3290---Volume-I</literal> will be literal,
170      byte for byte without any form of character normalization,
171      inserted into the index named <literal>oai:identifier</literal>,
172      the text 
173      <literal>Kumar Krishen and *Calvin Burnham, Editors</literal>
174      will be inserted using the <literal>w</literal> character
175      normalization defined in <filename>default.idx</filename> into
176      the index <literal>dc:creator</literal> (that is, after character
177      normalization the index will keep the inidividual words 
178      <literal>kumar</literal>, <literal>krishen</literal>, 
179      <literal>and</literal>, <literal>calvin</literal>,
180      <literal>burnham</literal>, and <literal>editors</literal>), and
181      finally both the texts
182      <literal>Proceedings of the 4th International Conference and Exhibition:
183       World Congress on Superconductivity - Volume I</literal> 
184      and
185      <literal>Kumar Krishen and *Calvin Burnham, Editors</literal> 
186      will be inserted into the index <literal>dc:all</literal> using
187      the same character normalization map <literal>w</literal>. 
188     </para>
189     <para>
190      Notice that there are no <filename>*.abs</filename>,
191      <filename>*.est</filename>, <filename>*.map</filename>, or other GRS-1
192      filter configuration files involves in this process. 
193     </para>
194    </sect2>
195   </sect1>
196
197
198   <sect1 id="record-model-alvisxslt-conf">
199    <title>ALVIS Record Model Configuration</title>
200
201
202   <sect2 id="record-model-alvisxslt-index">
203    <title>ALVIS Indexing Configuration</title>
204     <para>
205      As mentioned above, there can be only one indexing
206      stylesheet, and configuration of the indexing process is a synonym
207      of writing an XSLT stylesheet which produces XML output containing the
208      magic elements discussed in  
209      <xref linkend="record-model-alvisxslt-internal"/>. 
210      Obviously, there are million of different ways to accomplish this
211      task, and some comments and code snippets are in order to lead
212      our paduans on the right track to the  good side of the force.
213     </para>
214     <para>
215      Stylesheets can be written in the <emphasis>pull</emphasis> or
216      the <emphasis>push</emphasis> style: <emphasis>pull</emphasis>
217      means that the output XML structure is taken as starting point of
218      the internal structure of the XSLT stylesheet, and portions of
219      the input XML are <emphasis>pulled</emphasis> out and inserted
220      into the right spots of the output XML structure. On the other
221      side, <emphasis>push</emphasis> XSLT stylesheets are recursavly
222      calling their template definitions, a process which is commanded
223      by the input XML structure, and avake to produce some output XML
224      whenever some special conditions in the input styelsheets are
225      met. The <emphasis>pull</emphasis> type is well-suited for input
226      XML with strong and well-defined structure and semantcs, like the
227      following OAI indexing example, whereas the
228      <emphasis>push</emphasis> type might be the only possible way to
229      sort out deeply recursive input XML formats.
230     </para>
231     <para> 
232      A <emphasis>pull</emphasis> stylesheet example used to index
233      OAI harvested records could use some of the following template
234      definitions:
235      <screen>
236       <![CDATA[
237       <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
238        xmlns:z="http://indexdata.dk/zebra/xslt/1"
239        xmlns:oai="http://www.openarchives.org/OAI/2.0/" 
240        xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" 
241        xmlns:dc="http://purl.org/dc/elements/1.1/"
242        version="1.0">
243
244        <xsl:output indent="yes" method="xml" version="1.0" encoding="UTF-8"/>
245
246         <!-- disable all default text node output -->
247         <xsl:template match="text()"/>
248
249          <!-- match on oai xml record root -->
250          <xsl:template match="/">    
251           <z:record z:id="{normalize-space(oai:record/oai:header/oai:identifier)}" 
252            z:type="update">
253            <!-- you might want to use z:rank="{some XSLT function here}" --> 
254            <xsl:apply-templates/>
255           </z:record>
256          </xsl:template>
257
258          <!-- OAI indexing templates -->
259          <xsl:template match="oai:record/oai:header/oai:identifier">
260           <z:index name="oai:identifier" type="0">
261            <xsl:value-of select="."/>
262           </z:index>    
263          </xsl:template>
264
265          <!-- etc, etc -->
266
267          <!-- DC specific indexing templates -->
268          <xsl:template match="oai:record/oai:metadata/oai_dc:dc/dc:title">
269           <z:index name="dc:title" type="w">
270            <xsl:value-of select="."/>
271           </z:index>
272          </xsl:template>
273
274          <!-- etc, etc -->
275  
276       </xsl:stylesheet>
277       ]]>
278      </screen>
279     </para>
280     <para>
281      Notice also,
282      that the names and types of the indexes can be defined in the
283      indexing XSLT stylesheet <emphasis>dynamically according to
284      content in the original XML records</emphasis>, which has
285      opportunities for great power and wizardery as well as grande
286      disaster.  
287     </para>
288     <para>
289      The following excerpt of a <emphasis>push</emphasis> stylesheet
290      <emphasis>might</emphasis> 
291      be a good idea according to your strict control of the XML
292      input format (due to rigerours checking against well-defined and
293      tight RelaxNG or XML Schema's, for example):
294      <screen>
295       <![CDATA[
296       <xsl:template name="element-name-indexes">     
297        <z:index name="{name()}" type="w">
298         <xsl:value-of select="'1'"/>
299        </z:index>
300       </xsl:template>
301       ]]>
302      </screen>
303      This template creates indexes which have the name of the working 
304      node of any input  XML file, and assigns a '1' to the index.
305      The example query 
306      <literal>find @attr 1=xyz 1</literal> 
307      finds all files which contain at least one
308      <literal>xyz</literal> XML element. In case you can not control
309      which element names the input files contain, you might ask for
310      disaster and bad karma using this technique.
311     </para>
312     <para>
313      One variation over the theme <emphasis>dynamically created
314      indexes</emphasis> will definitely be unwise:
315      <screen>
316       <![CDATA[  
317       <!-- match on oai xml record root -->
318       <xsl:template match="/">    
319        <z:record z:type="update">
320       
321         <!-- create dynamic index name from input content --> 
322         <xsl:variable name="dynamic_content">
323          <xsl:value-of select="oai:record/oai:header/oai:identifier"/>
324         </xsl:variable>
325         
326         <!-- create zillions of indexes with unknown names -->
327         <z:index name="{$dynamic_content}" type="w">
328          <xsl:value-of select="oai:record/oai:metadata/oai_dc:dc"/>
329         </z:index>          
330        </z:record>
331        
332       </xsl:template>
333       ]]>
334      </screen>
335      Don't be tempted to cross
336      the line to the dark side of the force, paduan; this leads
337      to suffering and pain, and universal
338      disentigration of your project schedule.
339     </para>
340   </sect2>
341
342   <sect2 id="record-model-alvisxslt-elementset">
343    <title>ALVIS Exchange Formats</title>
344    <para>
345      An exchange format can be anything which can be the outcome of an
346      XSLT transformation, as far as the stylesheet is registered in
347      the main Alvis XSLT filter configuration file, see
348      <xref linkend="record-model-alvisxslt-filter"/>.
349      In principle anything that can be expressed in  XML, HTML, and
350      TEXT can be the output of a <literal>schema</literal> or 
351     <literal>element set</literal> directive during search, as long as
352      the information comes from the 
353      <emphasis>original input record XML DOM tree</emphasis>
354      (and not the transformed and <emphasis>indexed</emphasis> XML!!).
355     </para>
356     <para>
357      In addition, internal administrative information from the Zebra
358      indexer can be accessed during record retrieval. The following
359      example is a summary of the possibilities:
360      <screen>
361       <![CDATA[  
362       <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
363        xmlns:z="http://indexdata.dk/zebra/xslt/1"
364        version="1.0">
365
366        <!-- register internal zebra parameters -->       
367        <xsl:param name="id" select="''"/>
368        <xsl:param name="filename" select="''"/>
369        <xsl:param name="score" select="''"/>
370        <xsl:param name="schema" select="''"/>
371            
372        <xsl:output indent="yes" method="xml" version="1.0" encoding="UTF-8"/>
373
374        <!-- use then for display of internal information -->
375        <xsl:template match="/">
376          <z:zebra>
377            <id><xsl:value-of select="$id"/></id>
378            <filename><xsl:value-of select="$filename"/></filename>
379            <score><xsl:value-of select="$score"/></score>
380            <schema><xsl:value-of select="$schema"/></schema>
381          </z:zebra>
382        </xsl:template>
383
384       </xsl:stylesheet>
385       ]]>
386      </screen>
387     </para>
388
389   </sect2>
390
391   </sect1>
392
393   
394  </chapter>
395
396
397 <!--
398
399 c)  Main "alvis" XSLT filter config file:
400   cat db/filter_alvis_conf.xml 
401
402   <?xml version="1.0" encoding="UTF8"?>
403   <schemaInfo>
404     <schema name="alvis" stylesheet="db/alvis2alvis.xsl" />
405     <schema name="index" identifier="http://indexdata.dk/zebra/xslt/1"
406             stylesheet="db/alvis2index.xsl" />
407     <schema name="dc" stylesheet="db/alvis2dc.xsl" />
408     <schema name="dc-short" stylesheet="db/alvis2dc_short.xsl" />
409     <schema name="snippet" snippet="25" stylesheet="db/alvis2snippet.xsl" />
410     <schema name="help" stylesheet="db/alvis2help.xsl" />
411     <split level="1"/>
412   </schemaInfo>
413
414   the paths are relative to the directory where zebra.init is placed
415   and is started up.
416
417   The split level decides where the SAX parser shall split the
418   collections of records into individual records, which then are
419   loaded into DOM, and have the indexing XSLT stylesheet applied.
420
421   The indexing stylesheet is found by it's identifier.
422
423   All the other stylesheets are for presentation after search.
424
425 - in data/ a short sample of harvested carnivorous plants
426   ZEBRA_INDEX_DIRS=data/carnivor_20050118_2200_short-346.xml
427
428 - in root also one single data record - nice for testing the xslt
429   stylesheets,
430   
431   xsltproc db/alvis2index.xsl carni*.xml
432
433   and so on.
434
435 - in db/ a cql2pqf.txt yaz-client config file 
436   which is also used in the yaz-server <ulink url="http://www.loc.gov/standards/sru/cql/">CQL</ulink>-to-PQF process
437
438    see: http://www.indexdata.com/yaz/doc/tools.tkl#tools.cql.map
439
440 - in db/ an indexing XSLT stylesheet. This is a PULL-type XSLT thing,
441   as it constructs the new XML structure by pulling data out of the
442   respective elements/attributes of the old structure.
443
444   Notice the special zebra namespace, and the special elements in this
445   namespace which indicate to the zebra indexer what to do.
446
447   <z:record id="67ht7" rank="675" type="update">
448   indicates that a new record with given id and static rank has to be updated. 
449
450   <z:index name="title" type="w">
451    encloses all the text/XML which shall be indexed in the index named
452    "title" and of index type "w" (see  file default.idx in your zebra
453    installation) 
454
455
456    </para>
457
458    <para>
459 -->
460
461
462
463
464  <!-- Keep this comment at the end of the file
465  Local variables:
466  mode: sgml
467  sgml-omittag:t
468  sgml-shorttag:t
469  sgml-minimize-attributes:nil
470  sgml-always-quote-attributes:t
471  sgml-indent-step:1
472  sgml-indent-data:t
473  sgml-parent-document: "zebra.xml"
474  sgml-local-catalogs: nil
475  sgml-namecase-general:t
476  End:
477  -->