Appendix 5: Example Schemas for Indexing

This section contains some examples of schemas that define various different kinds of indices. The following cases are shown here:


Example 1: Simple Text Indexing

The following example illustrates how a simple Tamino query can be optimized by defining an appropriate index. For a full description of the query language, see the X-Query User Guide.

The example illustrate how the efficiency of retrieval operations can be influenced by intelligent indexing.

Specifying a tsd:index element with a tsd:text child element correctly stores the whole XML instance and performs full text indexing on the terminal nodes.

The hospital example is structured as shown in the picture:

Note:
The source of the hospital example is to be found in the section Examples of the appendix. Line numbers were added only for improving readability and easy reference.

graphics/patient4.gif

This picture shows the definition of the patient element within the hospital / patient schema example.

The corresponding schema looks like this:

Note:
The definition of an index takes place in the lines of code from 0870 to 1160 and also the lines 1340 to 1640:

0010 <?xml version="1.0" encoding="utf-8"?>
0020 <xs:schema>
0030   <xs:annotation>
0040     <xs:documentation></xs:documentation>
0050     <xs:appinfo>
0060       <tsd:schemaInfo name="patient"></tsd:schemaInfo>
0070     </xs:appinfo>
0080   </xs:annotation>
0090   <xs:element name="patient">
0100     <xs:annotation>
0110       <xs:documentation>Elements</xs:documentation>
0120     </xs:annotation>
0130     <xs:complexType>
0140       <xs:sequence>
0150         <xs:element ref="name" minOccurs="0"></xs:element>
0160         <xs:element ref="sex"></xs:element>
0170         <xs:element ref="born" minOccurs="0"></xs:element>
0180         <xs:element ref="address" minOccurs="0"></xs:element>
0190         <xs:element ref="occupation" minOccurs="0"></xs:element>
0200         <xs:element ref="insurance" minOccurs="0"></xs:element>
0210         <xs:element ref="nextofkin" minOccurs="0"></xs:element>
0220         <xs:element ref="submitted"></xs:element>
0230         <xs:element ref="examination" minOccurs="0" maxOccurs="unbounded">
0240         </xs:element>
0250         <xs:element ref="therapy" minOccurs="0"></xs:element>
0260         <xs:element ref="result" minOccurs="0"></xs:element>
0270         <xs:element ref="remarks" minOccurs="0" maxOccurs="unbounded">
0280         </xs:element>
0290       </xs:sequence>
0300       <xs:attribute name="id" type="xs:ID">
0310         <xs:annotation>
0320           <xs:documentation>Attributes</xs:documentation>
0330         </xs:annotation>
0340       </xs:attribute>
0350     </xs:complexType>
0360   </xs:element>
0370   <xs:element name="submitted">
0380     <xs:complexType>
0390       <xs:sequence>
0400         <xs:element ref="date"></xs:element>
0410         <xs:element ref="symptoms"></xs:element>
0420         <xs:element ref="diagnosis" maxOccurs="unbounded"></xs:element>
0430         <xs:element ref="doctor" maxOccurs="unbounded"></xs:element>
0440       </xs:sequence>
0450     </xs:complexType>
0460   </xs:element>
0470   <xs:element name="examination">
0480     <xs:complexType>
0490       <xs:sequence>
0500         <xs:element ref="date"></xs:element>
0510         <xs:element ref="report" minOccurs="0" maxOccurs="unbounded">
0520         </xs:element>
0530         <xs:element ref="remarks" minOccurs="0" maxOccurs="unbounded">
0540         </xs:element>
0550       </xs:sequence>
0560     </xs:complexType>
0570   </xs:element>
0580   <xs:element name="therapy">
0590     <xs:complexType>
0600       <xs:choice maxOccurs="unbounded">
0610         <xs:element ref="medication"></xs:element>
0620         <xs:element ref="physical"></xs:element>
0630         <xs:element ref="other"></xs:element>
0640       </xs:choice>
0650     </xs:complexType>
0660   </xs:element>
0670   <xs:element name="result">
0680     <xs:complexType>
0690       <xs:choice maxOccurs="unbounded">
0700         <xs:element ref="dismissed"></xs:element>
0710         <xs:element ref="transferred"></xs:element>
0720         <xs:element ref="deceased"></xs:element>
0730       </xs:choice>
0740     </xs:complexType>
0750   </xs:element>
0760   <xs:element name="remarks" type="xs:string"></xs:element>
0770   <xs:element name="name">
0780     <xs:complexType>
0790       <xs:sequence>
0800         <xs:element ref="surname"></xs:element>
0810         <xs:element ref="firstname"></xs:element>
0820         <xs:element ref="middlename" minOccurs="0"></xs:element>
0830         <xs:element ref="title" minOccurs="0"></xs:element>
0840       </xs:sequence>
0850     </xs:complexType>
0860   </xs:element>
0870   <xs:element name="surname" type="xs:string">
0880     <xs:annotation>
0890       <xs:appinfo>
0900         <tsd:elementInfo>
0910           <tsd:physical>
0920             <tsd:native>
0930               <tsd:index>
0940                 <tsd:text></tsd:text>
0950               </tsd:index>
0960             </tsd:native>
0970           </tsd:physical>
0980         </tsd:elementInfo>
0990       </xs:appinfo>
1000     </xs:annotation>
1010   </xs:element>
1020   <xs:element name="firstname" type="xs:string">
1030     <xs:annotation>
1040       <xs:appinfo>
1050         <tsd:elementInfo>
1060           <tsd:physical>
1070             <tsd:native>
1080               <tsd:index>
1090                 <tsd:text></tsd:text>
1100               </tsd:index>
1110             </tsd:native>
1120           </tsd:physical>
1130         </tsd:elementInfo>
1140       </xs:appinfo>
1150     </xs:annotation>
1160   </xs:element>
1170   <xs:element name="middlename" type="xs:string"></xs:element>
1180   <xs:element name="title" type="xs:string"></xs:element>
1190   <xs:element name="sex" type="xs:string"></xs:element>
1200   <xs:element name="born" type="xs:string"></xs:element>
1210   <xs:element name="address">
1220     <xs:complexType>
1230       <xs:sequence>
1240         <xs:element ref="street" minOccurs="0"></xs:element>
1250         <xs:element ref="housenumber" minOccurs="0"></xs:element>
1260         <xs:element ref="city" minOccurs="0"></xs:element>
1270         <xs:element ref="postcode" minOccurs="0"></xs:element>
1280         <xs:element ref="country" minOccurs="0"></xs:element>
1290         <xs:element ref="phone" minOccurs="0" maxOccurs="unbounded">
1300         </xs:element>
1310       </xs:sequence>
1320     </xs:complexType>
1330   </xs:element>
1340   <xs:element name="street" type="xs:string">
1350     <xs:annotation>
1360       <xs:appinfo>
1370         <tsd:elementInfo>
1380           <tsd:physical>
1390             <tsd:native>
1400               <tsd:index>
1410                 <tsd:text></tsd:text>
1420               </tsd:index>
1430             </tsd:native>
1440           </tsd:physical>
1450         </tsd:elementInfo>
1460       </xs:appinfo>
1470     </xs:annotation>
1480   </xs:element>
1490   <xs:element name="housenumber" type="xs:string"></xs:element>
1500   <xs:element name="city" type="xs:string">
1510     <xs:annotation>
1520       <xs:appinfo>
1530         <tsd:elementInfo>
1540           <tsd:physical>
1550             <tsd:native>
1560               <tsd:index>
1570                 <tsd:text></tsd:text>
1580               </tsd:index>
1590             </tsd:native>
1600           </tsd:physical>
1610         </tsd:elementInfo>
1620       </xs:appinfo>
1630     </xs:annotation>
1640   </xs:element>
1650   <xs:element name="postcode" type="xs:string"></xs:element>
1660   <xs:element name="country" type="xs:string"></xs:element>
1670   <xs:element name="occupation" type="xs:string"></xs:element>
1680   <xs:element name="insurance">
1690     <xs:complexType>
1700       <xs:sequence>
1710         <xs:element ref="company"></xs:element>
1720         <xs:element ref="policynumber" minOccurs="0"></xs:element>
1730       </xs:sequence>
1740     </xs:complexType>
1750   </xs:element>
1760   <xs:element name="company" type="xs:string"></xs:element>
1770   <xs:element name="policynumber" type="xs:string"></xs:element>
1780   <xs:element name="nextofkin">
1790     <xs:complexType>
1800       <xs:sequence>
1810         <xs:element ref="name"></xs:element>
1820         <xs:element ref="address" minOccurs="0"></xs:element>
1830         <xs:element ref="phone" minOccurs="0" maxOccurs="unbounded">
1840         </xs:element>
1850         <xs:element ref="fax" minOccurs="0"></xs:element>
1860       </xs:sequence>
1870       <xs:attribute name="grade" type="xs:string" use="required">
1880       </xs:attribute>
1890     </xs:complexType>
1900   </xs:element>
1910   <xs:element name="phone" type="xs:string"></xs:element>
1920   <xs:element name="fax" type="xs:string"></xs:element>
1930   <xs:element name="date" type="xs:string"></xs:element>
1940   <xs:element name="report">
1950     <xs:complexType>
1960       <xs:attribute name="files" type="xs:ENTITIES" use="required">
1970       </xs:attribute>
1980     </xs:complexType>
1990   </xs:element>
2000   <xs:element name="symptoms" type="xs:string"></xs:element>
2010   <xs:element name="diagnosis" type="xs:string"></xs:element>
2020   <xs:element name="doctor">
2030     <xs:complexType>
2040       <xs:sequence>
2050         <xs:element ref="name"></xs:element>
2060       </xs:sequence>
2070       <xs:attribute name="pager" type="xs:string"></xs:attribute>
2080     </xs:complexType>
2090   </xs:element>
2100   <xs:element name="medication">
2110     <xs:complexType>
2120       <xs:sequence maxOccurs="unbounded">
2130         <xs:element ref="type"></xs:element>
2140         <xs:element ref="dosage"></xs:element>
2150       </xs:sequence>
2160     </xs:complexType>
2170   </xs:element>
2180   <xs:element name="type">
2190     <xs:complexType>
2200       <xs:simpleContent>
2210         <xs:extension base="xs:string">
2220           <xs:attribute name="form" use="required">
2230             <xs:simpleType>
2240               <xs:restriction base="xs:NMTOKEN">
2250                 <xs:enumeration value="tablet"></xs:enumeration>
2260                 <xs:enumeration value="capsule"></xs:enumeration>
2270                 <xs:enumeration value="drops"></xs:enumeration>
2280                 <xs:enumeration value="intravenous"></xs:enumeration>
2290               </xs:restriction>
2300             </xs:simpleType>
2310           </xs:attribute>
2320           <xs:attribute name="brand" type="xs:string"></xs:attribute>
2330         </xs:extension>
2340       </xs:simpleContent>
2350     </xs:complexType>
2360   </xs:element>
2370   <xs:element name="dosage" type="xs:string"></xs:element>
2380   <xs:element name="physical">
2390     <xs:complexType>
2400       <xs:sequence>
2410         <xs:element ref="description"></xs:element>
2420         <xs:element ref="frequency" minOccurs="0"></xs:element>
2430       </xs:sequence>
2440     </xs:complexType>
2450   </xs:element>
2460   <xs:element name="description" type="xs:string"></xs:element>
2470   <xs:element name="frequency" type="xs:string"></xs:element>
2480   <xs:element name="other">
2490     <xs:complexType>
2500       <xs:sequence>
2510         <xs:element ref="description"></xs:element>
2520         <xs:element ref="amount" minOccurs="0"></xs:element>
2530       </xs:sequence>
2540     </xs:complexType>
2550   </xs:element>
2560   <xs:element name="amount" type="xs:string"></xs:element>
2570   <xs:element name="dismissed">
2580     <xs:complexType>
2590       <xs:sequence>
2600         <xs:element ref="date"></xs:element>
2610         <xs:element ref="doctor" minOccurs="0"></xs:element>
2620       </xs:sequence>
2630     </xs:complexType>
2640   </xs:element>
2650   <xs:element name="transferred">
2660     <xs:complexType>
2670       <xs:sequence>
2680         <xs:element ref="date"></xs:element>
2690         <xs:element ref="destination"></xs:element>
2700         <xs:element ref="doctor" minOccurs="0"></xs:element>
2710       </xs:sequence>
2720     </xs:complexType>
2730   </xs:element>
2740   <xs:element name="destination" type="xs:string"></xs:element>
2750   <xs:element name="deceased">
2760     <xs:complexType>
2770       <xs:sequence>
2780         <xs:element ref="date"></xs:element>
2790         <xs:element ref="doctor" minOccurs="0"></xs:element>
2800       </xs:sequence>
2810     </xs:complexType>
2820   </xs:element>
2830 </xs:schema>

Example 2: Simple Standard Indexing

Imagine the schema of the example above would have been changed by the following schema fragment concerning the definition of a standard index for the element called surname of type xs:string:

	       .
        .
        .
        <xs:element name = "surname" type = "xs:string">
          <xs:annotation>
            <xs:appinfo>
              <tsd:elementInfo>
                <tsd:physical>
                  <tsd:native>
                    <tsd:index>
                      <tsd:standard/>
                    </tsd:index>
                  </tsd:native>
                </tsd:physical>
              </tsd:elementInfo>
            </xs:appinfo>
          </xs:annotation>
        </xs:element>
	       .
        .
        .

This would lead to the creation of a standard index instead of a text index for the element surname.

See also the description of tsd:index.

Example 3: Defining a Compound Index

This example schema provides four elements located on 3 different levels, whereby A and B are of multiplicity greater than 1:

  1. An element A one stage below root level

  2. A child element of A named B

  3. Two child elements of B named C and D.

On B, a compound index is declared for the children C and D which are of datatype "string" and of datatype "integer", respectively.

Note:
The definition of a compound index takes place in the lines of code from 250 to 300.

010 <?xml version="1.0" encoding="utf-8"?>
020 <xs:schema xmlns:tsd="http://namespaces.softwareag.com/tamino/TaminoSchemaDefinition"
030            xmlns:xs="http://www.w3.org/2001/XMLSchema">
040   <xs:annotation>
050     <xs:appinfo>
060       <tsd:schemaInfo name="DocTreeIndex">
070         <tsd:collection name="DocTreeIndex"></tsd:collection>
080         <tsd:doctype name="Doc" />
090         <tsd:doctype name="Doc1" />
100       </tsd:schemaInfo>
110     </xs:appinfo>
120   </xs:annotation>
130   <xs:element name="Doc">
140     <xs:complexType>
150       <xs:sequence>
160         <xs:element name="A" maxOccurs="unbounded">
170           <xs:complexType>
180             <xs:sequence>
190               <xs:element name="B" maxOccurs="unbounded">
200                 <xs:annotation>
210                   <xs:appinfo>
220                     <tsd:elementInfo>
230                       <tsd:physical>
240                         <tsd:native>
250                           <tsd:index>
260                             <tsd:standard>
270                               <tsd:field xpath="C" />
280                               <tsd:field xpath="D" />
290                             </tsd:standard>
300                           </tsd:index>
310                         </tsd:native>
320                       </tsd:physical>
330                     </tsd:elementInfo>
340                   </xs:appinfo>
350                 </xs:annotation>
360                 <xs:complexType>
370                   <xs:sequence>
380                     <xs:element name="C" type="xs:string"></xs:element>
390                     <xs:element name="D" type="xs:integer"></xs:element>
400                   </xs:sequence>
410                 </xs:complexType>
420               </xs:element>
430             </xs:sequence>
440           </xs:complexType>
450         </xs:element>
460         <xs:element name="refDoc1" type="xs:string"></xs:element>
470       </xs:sequence>
480     </xs:complexType>
490   </xs:element>
500   <xs:element name="Doc1">
510     <xs:complexType>
520       <xs:sequence>
530         <xs:element name="A1" type="xs:string">
540           <xs:annotation>
550             <xs:appinfo>
560               <tsd:elementInfo>
570                 <tsd:physical>
580                   <tsd:native>
590                     <tsd:index>
600                       <tsd:standard></tsd:standard>
610                     </tsd:index>
620                   </tsd:native>
630                 </tsd:physical>
640               </tsd:elementInfo>
650             </xs:appinfo>
660           </xs:annotation>
670         </xs:element>
680         <xs:element name="F" type="xs:string"></xs:element>
690       </xs:sequence>
700     </xs:complexType>
710   </xs:element>
720 </xs:schema>

Example 4: Defining a Multipath Index

The schema must provide the path /Doc/A/E to the node F. The node E has a recursive structure E->E. F has a multiple path index of type standard with datatype xs:string. Below the node A as well the sub-tree B with C and D are defined. A and B are without multiplicity greater than 1.

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:tsd="http://namespaces.softwareag.com/tamino/TaminoSchemaDefinition"
           xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:annotation>
    <xs:appinfo>
      <tsd:schemaInfo name="DocRecursive">
        <tsd:collection name="DocRecursive"></tsd:collection>
        <tsd:doctype name="Doc">
          <tsd:logical>
            <tsd:content>closed</tsd:content>
          </tsd:logical>
        </tsd:doctype>
      </tsd:schemaInfo>
    </xs:appinfo>
  </xs:annotation>
  <xs:element name="Doc">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="A">
          <xs:complexType>
            <xs:sequence>
              <xs:element ref="E"></xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="B">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="C" type="xs:string">
                <xs:annotation>
                  <xs:appinfo>
                    <tsd:elementInfo>
                      <tsd:physical>
                        <tsd:native>
                          <tsd:index>
                            <tsd:standard></tsd:standard>
                          </tsd:index>
                        </tsd:native>
                      </tsd:physical>
                    </tsd:elementInfo>
                  </xs:appinfo>
                </xs:annotation>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="E">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="E" minOccurs="0"></xs:element>
        <xs:element name="F" type="xs:string">
          <xs:annotation>
            <xs:appinfo>
              <tsd:elementInfo>
                <tsd:physical>
                  <tsd:native>
                    <tsd:index>
                      <tsd:standard>
                        <tsd:multiPath />
                      </tsd:standard>
                    </tsd:index>
                  </tsd:native>
                </tsd:physical>
              </tsd:elementInfo>
            </xs:appinfo>
          </xs:annotation>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Example 5: Combining Various Indexing Techniques at One Single Node

This example shows how four different coexisting indices are defined in parallel, namely a simple text index, a simple standard index and two different compound indices:

<xs:element ...>
  ...
  <tsd:elementInfo>
    <tsd:physical>
     [<tsd:which>...</tsd:which>]
      <tsd:native>
        <tsd:index>
          <tsd:text/>
          <tsd:standard/>
          <tsd:standard>
            <tsd:field xpath="C"/>
            <tsd:field xpath="B/@b" />
          </tsd:standard >
          <tsd:standard>
            <tsd:field xpath="D"/>
            <tsd:field xpath="B/@b" />
          </tsd:standard >
          ...
        </tsd:index>
      </tsd:native>
    </tsd:physical>
  </tsd:elementInfo>
</xs:element>

Example 6: Defining a Reference Index

This example schema provides 3 levels of references:

  1. the document root;

  2. A appearing with multiplicity greater than 1;

  3. B appearing with multiplicity greater than 1.

Below B there are two nodes C and D which have indices (one of type text and one type standard with datatype integer), which refer to B. On B a reference index is declared, which points to A and A refers to the document root.

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:tsd="http://namespaces.softwareag.com/tamino/TaminoSchemaDefinition"
           xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:annotation>
    <xs:appinfo>
      <tsd:schemaInfo name="DocTreeIndex">
        <tsd:collection name="DocTreeIndex"></tsd:collection>
        <tsd:doctype name="Doc" />
        <tsd:doctype name="Doc1" />
      </tsd:schemaInfo>
    </xs:appinfo>
  </xs:annotation>
  <xs:element name="Doc">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="A" maxOccurs="unbounded">
          <xs:annotation>
            <xs:appinfo>
              <tsd:elementInfo>
                <tsd:physical>
                  <tsd:native>
                    <tsd:index>
                      <tsd:reference />
                    </tsd:index>
                  </tsd:native>
                </tsd:physical>
              </tsd:elementInfo>
            </xs:appinfo>
          </xs:annotation>
          <xs:complexType>
            <xs:sequence>
              <xs:element name="B" maxOccurs="unbounded">
                <xs:annotation>
                  <xs:appinfo>
                    <tsd:elementInfo>
                      <tsd:physical>
                        <tsd:native>
                          <tsd:index>
                            <tsd:reference>
                              <tsd:refers>/Doc/A</tsd:refers>
                            </tsd:reference>
                          </tsd:index>
                        </tsd:native>
                      </tsd:physical>
                    </tsd:elementInfo>
                  </xs:appinfo>
                </xs:annotation>
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="C" type="xs:string">
                      <xs:annotation>
                        <xs:appinfo>
                          <tsd:elementInfo>
                            <tsd:physical>
                              <tsd:native>
                                <tsd:index>
                                  <tsd:text>
                                    <tsd:refers>/Doc/A/B</tsd:refers>
                                  </tsd:text>
                                </tsd:index>
                              </tsd:native>
                            </tsd:physical>
                          </tsd:elementInfo>
                        </xs:appinfo>
                      </xs:annotation>
                    </xs:element>
                    <xs:element name="D" type="xs:integer">
                      <xs:annotation>
                        <xs:appinfo>
                          <tsd:elementInfo>
                            <tsd:physical>
                              <tsd:native>
                                <tsd:index>
                                  <tsd:standard>
                                    <tsd:refers>/Doc/A/B</tsd:refers>
                                  </tsd:standard>
                                </tsd:index>
                              </tsd:native>
                            </tsd:physical>
                          </tsd:elementInfo>
                        </xs:appinfo>
                      </xs:annotation>
                    </xs:element>
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="refDoc1" type="xs:string"></xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="Doc1">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="A1" type="xs:string">
          <xs:annotation>
            <xs:appinfo>
              <tsd:elementInfo>
                <tsd:physical>
                  <tsd:native>
                    <tsd:index>
                      <tsd:standard></tsd:standard>
                    </tsd:index>
                  </tsd:native>
                </tsd:physical>
              </tsd:elementInfo>
            </xs:appinfo>
          </xs:annotation>
        </xs:element>
        <xs:element name="F" type="xs:string"></xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Example 7: Defining a Computed Index

This example illustrates three different types or levels of usage of computed indexes:

basic usage;
a pseudo-compound index concatenating two strings with a delimiter;
for sorting.

As described in the Performance Guide, section Advanced Indexes, a computed index and its usage consist of several components as given below:

XQuery Module

module namespace demo="http://example.computedIndex.org"

declare function demo:getTitleLowerCase($in as node()) as xs:string*
{
	for $t in $in//title
	return lower-case(string($t))
}

declare function demo:getAuthorFullName($in as node()) as xs:string*
{
	for $a in $in//author
	return string-join( ( string($a/last), string($a/first) ), "," )
}

declare function demo:getAuthorsTotalNameLength($in as node()) as xs:integer
{
  	xs:integer(sum(
	  for $a in $in//author
	  return string-length(string($a/last))
	))
}

Schema

<?xml version = "1.0" encoding = "UTF-8"?>
<xs:schema xmlns:xs = "http://www.w3.org/2001/XMLSchema" xmlns:tsd = "http://namespaces.softwareag.com/tamino/TaminoSchemaDefinition">
  <xs:annotation>
    <xs:appinfo>
      <tsd:schemaInfo name = "books" xmlns:tsd="http://namespaces.softwareag.com/tamino/TaminoSchemaDefinition">
        <tsd:collection name = "mybib"/>
        <tsd:doctype name = "bib">
          <tsd:physical>
            <tsd:index>
              <tsd:standard>
                <tsd:computed name='compIndex-1' function='p:getTitleLowerCase' 
 				type='xs:string' xmlns:p='http://example.computedIndex.org'/>
              </tsd:standard>
              <tsd:standard>
                <tsd:computed name='compIndex-2' function='p:getAuthorFullName' 
 				type='xs:string' xmlns:p='http://example.computedIndex.org'/>
              </tsd:standard>
              <tsd:standard>
                <tsd:computed name='compIndex-3' function='p:getAuthorsTotalNameLength' 
 				type='xs:int' xmlns:p='http://example.computedIndex.org'/>
              </tsd:standard>
            </tsd:index>
          </tsd:physical>
        </tsd:doctype>
      </tsd:schemaInfo>
    </xs:appinfo>
  </xs:annotation>
  <xs:element name = "bib">
    <xs:complexType>
      <xs:sequence>
      <xs:choice>
        <xs:element ref = "book"></xs:element>
        <xs:element ref = "article"></xs:element>
      </xs:choice>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
   <xs:element name = "article">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref = "title"></xs:element>
        <xs:choice>
          <xs:element ref = "author" maxOccurs = "unbounded"></xs:element>
          <xs:element ref = "editor" maxOccurs = "unbounded"></xs:element>
        </xs:choice>
      </xs:sequence>
      <xs:attribute name = "year" type = "xs:integer" use = "required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name = "book">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref = "title"></xs:element>
        <xs:choice>
          <xs:element ref = "author" maxOccurs = "unbounded"></xs:element>
          <xs:element ref = "editor" maxOccurs = "unbounded"></xs:element>
        </xs:choice>
        <xs:element ref = "publisher"></xs:element>
        <xs:element ref = "price"></xs:element>
      </xs:sequence>
      <xs:attribute name = "year" type = "xs:integer" use = "required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name = "author">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref = "last"></xs:element>
        <xs:element ref = "first"></xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name = "editor">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref = "last"></xs:element>
        <xs:element ref = "first"></xs:element>
        <xs:element ref = "affiliation"></xs:element>
      </xs:sequence>
      <xs:attribute name = "year" type = "xs:integer" use = "required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name = "publisher">
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base = "xs:string">
          <xs:attribute name = "year" type = "xs:string" use = "required"/>
        </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
  </xs:element>
  <xs:element name = "title" type = "xs:string"/>
  <xs:element name = "last" type = "xs:string"/>
  <xs:element name = "first" type = "xs:string"/>
  <xs:element name = "affiliation" type = "xs:string"/>
  <xs:element name = "price" type = "xs:string"/>
</xs:schema>

XQuery

The following XQuery statements are evaluated using the computed indexes defined above:

import module namespace demo='http://example.computedIndex.org';
for $x in collection(‘mybib’)/bib
where demo:getTitleLowerCase(root($x))='tcp/ip illustrated'
return $x

import module namespace demo='http://example.computedIndex.org';
for $x in collection(‘mybib’)/bib
where demo:getAuthorFullName(root($x)) = 'Stevens,W.'
return $x

import module namespace demo='http://example.computedIndex.org';
for $x in collection(‘mybib’)/bib
order by demo:getAuthorsTotalNameLength(root($x))" 
return $x

Note that all of these XQuery statements using the respective XQuery functions receive the document root as input parameter. This is required in order to enable the XQuery processor to take advantage of using the computed index.

Data

The following data can be used to test the computed indexes as defined above:

<bib>
    <book year="1994">
        <title>TCP/IP Illustrated</title>
        <author><last>Stevens</last><first>W.</first></author>
        <publisher year="1990">Addison-Wesley</publisher>
        <price>65.95</price>
    </book>
</bib>
<bib>
    <book year="1992">
        <title>Advanced Programming in the Unix environment</title>
        <author><last>Stevens</last><first>W.</first></author>
        <publisher year="2000">Addison-Wesley</publisher>
        <price>65.95</price>
    </book>
</bib>
<bib>
    <book year="2000">
        <title>Data on the Web</title>
        <author><last>Abiteboul</last><first>Serge</first></author>
        <author><last>Buneman</last><first>Peter</first></author>
        <author><last>Suciu</last><first>Dan</first></author>
        <publisher year="2001">Morgan Kaufmann Publishers</publisher>
        <price>39.95</price>
    </book>
</bib>
<bib>
    <book year="1999">
        <title>The Economics of Technology and Content for Digital TV</title>
        <editor year="1973">
               <last>Gerbarg</last><first>Darcy</first>
               <affiliation>CITI</affiliation>
        </editor>
        <publisher year="2002">Kluwer Academic Publishers</publisher>
        <price>129.95</price>
    </book>
</bib>
<bib>
    <book year="1985">
        <title>Computer-Aided Database Design: the DATAID approach</title>
        <author><last>Di Leva</last><first>Antonio</first></author>
        <author><last>Albano</last><first>Antonio</first></author>
        <publisher year="1985">North-Holland</publisher>
        <price>12.95</price>
    </book>
</bib>
<bib>
    <article year="1999">
        <title>The Economics of Technology and Content for Digital TV</title>
        <editor year="1973">
               <last>Gerbarg</last><first>Darcy</first>
               <affiliation>CITI</affiliation>
        </editor>
    </article>
</bib>