vladimir 2002/11/17 00:16:03
Added: src/documentation/content/xdocs/dev book.xml
guide-administrator.xml guide-commandline.xml
guide-developer.xml guide-user.xml index.xml
news.xml
Log:
initial import
Revision Changes Path
1.1 xml-xindice/src/documentation/content/xdocs/dev/book.xml
Index: book.xml
===================================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//APACHE//DTD Cocoon Documentation Book V1.0//EN"
"book-cocoon-v10.dtd">
<!--
- Version: $Revision: 1.1 $ $Date: 2002/11/17 08:16:03 $
- Author: Vladimir R. Bossicard ([EMAIL PROTECTED])
-->
<book software="Xindice"
title="Xindice development zone"
copyright="2002 The Apache Foundation"
xmlns:xlink="http://www.w3.org/1999/xlink">
<menu label="Project">
<menu-item label="Overview" href="index.html"/>
<menu-item label="News" href="news.html"/>
</menu>
<menu label="Documentation">
<menu-item label="Administrator Guide" href="guide-administrator.html"/>
<menu-item label="User Guide" href="guide-user.html"/>
<menu-item label="Developer Guide" href="guide-developer.html"/>
<menu-item label="Commandline Tool Guide"
href="guide-commandline.html"/>
</menu>
</book>
1.1
xml-xindice/src/documentation/content/xdocs/dev/guide-administrator.xml
Index: guide-administrator.xml
===================================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN"
"document-v11.dtd">
<!--
- Version: $Revision: 1.1 $ $Date: 2002/11/17 08:16:03 $
- Author: Kimbro Staken ([EMAIL PROTECTED])
-->
<document>
<header>
<title>Administrator guide</title>
<authors>
<person id="ks" name="Kimbro Staken" email=""/>
</authors>
<notice/>
<abstract/>
</header>
<body>
<warning>This documentation is a work in progress and is only
applicable to the CVS version of Xindice. There is absolutely no guarantee that
this information is accurate. You have been warned.
</warning>
<section>
<title>Database Administration</title>
<p>
Database administration of Xindice is accomplished from the
command
line using the
<code>xindice</code> command. This command
allows you to view and alter the database configuration on the fly
on a running system. A complete list of available commands and
more
detail about each command can be found in the
<link href="guide-tools.html">Command Line Tools Reference
Guide</link>.
</p>
<section>
<title>Managing Collections</title>
<p/>
<section>
<title>Adding a Collection</title>
<p>
Adds a collection named products under the collection
/db/data.
</p>
<source>xindice add_collection -c /db/data -n products</source>
</section>
<section>
<title>Deleting a Collection</title>
<p>Deletes the collection named products from the collection
/db/data.</p>
<source>xindice delete_collection -c /db/data/products</source>
</section>
<section>
<title>Listing the Collections</title>
<p>This will display a list of all child collections under the
collection /db/data</p>
<source>xindice list_collections -c /db/data</source>
</section>
</section>
<section>
<title>Managing Indexes</title>
<p>
The Xindice indexing system allows you to define indexes to
speed
performance on commonly used XPath queries. If no indexes are
defined
you can still execute queries but performance will suffer
because the
query engine will need to scan the entire collection to create
the
result node-set.
</p>
<p>
Indexes can be added using the
<code>xindice</code>
command.
</p>
<section>
<title>Adding an Index</title>
<p>
Using this simple XML file you might want to index the
product_id
element because searches for products by product_id are
common.
</p>
<source><![CDATA[
<?xml version="1.0"?>
<product>
<product_id>120320</product_id>
<description>Glazed Ham</description>
</product>]]></source>
<p>
This can be accomplished by running the following command.
This will create an index named idindex on all product_id
elements in the collection /db/data/catalog.
</p>
<source><![CDATA[
xindice add_indexer -c /db/data/catalog -n idindex -p product_id
]]></source>
<p>
Once this is done the query engine will now use this index
to
help resolve XPath queries that involve restriction on the
value of the product_id element.
</p>
</section>
<p>
The -p parameter to the command specifies the pattern to use
in the
index. These patterns are used by the Indexing system to
determine
best-fit and match-based Indexers for queries and index
updating.
The pattern used
MUST resemble the following scheme.
</p>
<source>
<![CDATA[
Pattern Description
=========== ====================================================
elem The value of the named element
[EMAIL PROTECTED] The value of the attribute for the named element
* The value for all elements
[EMAIL PROTECTED] The value of the named attribute for all
elements
[EMAIL PROTECTED] The value of all attributes for the named element
[EMAIL PROTECTED] The value of all attributes for all elements
]]></source>
<p>
Note: In order to index a namespace other than the default
namespace, you must prepend your pattern components with a
URI placed in square brackets. Example:
</p>
<source><![CDATA[
[http://www.world.org/People]person
[EMAIL PROTECTED]://www.world.org/People]id
[http://www.world.org/[EMAIL PROTECTED]://www.world.org/People]id
]]></source>
<p>
Do not include a prefix in these patterns, as the indexing
system, like most Namespace processing applications, processes
namespaced elements and attributes independently of the prefix
that is used.
</p>
<section>
<title>Indexing both Elements and Attributes</title>
<p>
Because the patterns recognize either an element or an
attribute,
and not both, in order to index all element and attribute
values
in a collection, you'd have to create two index entries.
The *
pattern will index all elements and the [EMAIL PROTECTED]
pattern will index
all attributes of all elements.
</p>
<source><![CDATA[
xindice add_collection_indexer -c /db/data/catalog -n idindex -p '*'
xindice add_collection_indexer -c /db/data/catalog -n idindex -p '[EMAIL
PROTECTED]'
]]></source>
</section>
<p>
Excessive use of wildcard indexes can adversely affect the
performance of the indexing system. Best practice would be to use
specific element or attribute indexes whenever possible, and only
define wildcard indexes when it is absolutely necessary.
</p>
</section>
</section>
<section>
<title>Server Administration</title>
<section>
<title>Starting the Server</title>
<p>
The server must be started from within the Xindice directory.
A future revision of the server will fix this limitation.
</p>
<section>
<title>Starting the Server on UNIX</title>
<source><![CDATA[
cd Xindice
./start
]]></source>
</section>
<section>
<title>Starting the Server on Windows</title>
<source><![CDATA[
cd Xindice
startup
]]></source>
</section>
</section>
<section>
<title>Stopping the Server</title>
<p>
The Xindice server can be easily shutdown from the command line. You
must provide the name of the server instance to shutdown.
</p>
<section>
<title>Stopping the Server</title>
<p>
This example assumes that the Xindice/bin directory
is in your path.
</p>
<source><![CDATA[
xindice shutdown -c /db
]]></source>
</section>
</section>
<section>
<title>Backing up Your Data</title>
<p>
Currently backing up Xindice consists of simply shutting down the
server and copying the
entire contents of the Xindice/db directory to the backup
media.
</p>
<section>
<title>Backing up the server</title>
<p>
This example assumes that the Xindice/bin directory
is in your path.
</p>
<source><![CDATA[
cd Xindice
xindice shutdown
cp -pr db /backup/db
./start
]]></source>
</section>
<section>
<title>Restoring the Data</title>
<p>
Restoring the data is simply removing the current database and
reversing the backup process.
This example assumes that the Xindice/bin directory
is in your path.
</p>
<source><![CDATA[
cd Xindice
xindice shutdown
rm -rf db
cp -pr /backup/db db
./start
]]></source>
</section>
</section>
<section>
<title>Exporting the Contents of the Database</title>
<p>
Xindice includes tools to export data to a directory hierarchy and
to also import
data from a directory hierarchy. Each directory in the hierachy
corresponds to a
collection in Xindice. Each XML document is stored in a separate
file named with
the key from the database.
</p>
<section>
<title>Exporting the database</title>
<p>
This example assumes that the Xindice/bin directory
is in your path.
</p>
<source><![CDATA[
xindice export -c /db/root -f /path/to/data
]]></source>
<p>
The entire contents of the collection /db/root will be exported
to the
directory /path/to/data.
</p>
</section>
<section>
<title>Importing the database</title>
<p>
This example assumes that the Xindice/bin directory
is in your path.
</p>
<source><![CDATA[
xindice import -c /db -f /path/to/data/root
]]></source>
<p>
Each directory under /path/to/data will be used to create a
collection and
all XML documents in the hierarchy will be imported in to the
database. You
can also restrict the documents that are imported by adding -i
and the
extension of the files you want to import.
</p>
</section>
</section>
</section>
</body>
</document>
1.1
xml-xindice/src/documentation/content/xdocs/dev/guide-commandline.xml
Index: guide-commandline.xml
===================================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN"
"document-v11.dtd">
<!--
- Version: $Revision: 1.1 $ $Date: 2002/11/17 08:16:03 $
- Author: Kimbro Staken ([EMAIL PROTECTED])
-->
<document>
<header>
<title>Commandline Tool Guide</title>
<authors>
<person id="jk" name="Jay Kalafus" email=""/>
<person id="ks" name="Kimbro Staken" email=""/>
</authors>
<notice/>
<abstract/>
</header>
<body>
<warning>This documentation is a work in progress and is only
applicable to the CVS version of Xindice. There is absolutely no guarantee that
this information is accurate. You have been warned.
</warning>
<section>
<title>Collection Management Commands</title>
<section>
<title>Adding a Collection</title>
<p>
Adds a new collection to the database. When adding a collection
under an existing collection hierarchy all parent collections
must
already exist in the database.
</p>
<section>
<title>Summary:</title>
</section>
<p>
<code>xindice add_collection-c
(or context)
-n
(or name)
[-v
(or )
]
</code>
</p>
<table>
<tr>
<td>Action:</td>
<td>
<code>add_collection</code>
</td>
</tr>
<tr>
<td>Abberviated-Action:</td>
<td>
<code>ac</code>
</td>
</tr>
<tr>
<td>Access Level:</td>
<td>Admin</td>
</tr>
</table>
<section>
<title>Parameters:</title>
</section>
<ul>
<li>
<code>-c</code> The collection context under which to
create the new
collection.
</li>
<li>
<code>-n</code> The name of the collection to create
</li>
<li>
<code>-v</code> Show verbose output
</li>
</ul>
<section>
<title>Examples:</title>
</section>
<section>
<title>Creating a Top Level Collection</title>
<source><![CDATA[
xindice add_collection -c /db -n pebbles
]]></source>
</section>
<section>
<title>Creating a Sub Collection Under an Existing
Collection</title>
<source><![CDATA[
xindice add_collection -c /db/pebbles -n boulder
]]></source>
</section>
</section>
<section>
<title>Deleting a Collection</title>
<p>
Deletes a collection or subcollection from the database. If
deleting a collection that has subcollections and documents
they will also be deleted.
</p>
<section>
<title>Summary:</title>
</section>
<p>
<code>xindice delete_collection-c
(or context)
-n
(or name)
[-v
(or )
]
</code>
</p>
<table>
<tr>
<td>Action:</td>
<td>
<code>delete_collection</code>
</td>
</tr>
<tr>
<td>Abberviated-Action:</td>
<td>
<code>dc</code>
</td>
</tr>
<tr>
<td>Access Level:</td>
<td>Admin</td>
</tr>
</table>
<section>
<title>Parameters:</title>
</section>
<ul>
<li>
<code>-c</code> The collection context under which to
delete the collection.
</li>
<li>
<code>-n</code> The name of the collection to delete.
</li>
<li>
<code>-v</code> Show verbose output
</li>
</ul>
<section>
<title>Examples:</title>
</section>
<section>
<title>Deleting a Top Level Collection</title>
<source><![CDATA[
xindice delete_collection -c /db -n pebbles
]]></source>
</section>
<section>
<title>Deleting a Sub Collection</title>
<source><![CDATA[
xindice delete_collection -c /db/pebbles -n boulder
]]></source>
</section>
</section>
<section>
<title>List Collections</title>
<p>
List all collections under the collection context given. If
no collection is given then the root
collection will be asumed.
</p>
<section>
<title>Summary:</title>
</section>
<p>
<code>xindice list_collections
[-c
(or context)
]
[-v
(or )
]
</code>
</p>
<table>
<tr>
<td>Action:</td>
<td>
<code>list_collections</code>
</td>
</tr>
<tr>
<td>Abberviated-Action:</td>
<td>
<code>lc</code>
</td>
</tr>
<tr>
<td>Access Level:</td>
<td>User</td>
</tr>
</table>
<section>
<title>Parameters:</title>
</section>
<ul>
<li>
<code>-c</code> The collection context under which all sub
collections are listed
</li>
<li>
<code>-v</code> Show verbose output
</li>
</ul>
<section>
<title>Examples:</title>
</section>
<section>
<title>Listing the Top Level Collections</title>
<source><![CDATA[
xindice list_collections -c /db
]]></source>
</section>
<section>
<title>Listing a Sub Collection</title>
<source><![CDATA[
xindice list_collections -c /db/pebbles
]]></source>
</section>
</section>
</section>
<section>
<title>Document Management Commands</title>
<section>
<title>Adding a Document</title>
<p>
Adds a document to a collection or nested collection. Adding
a document requires two parameters -
the collection it will be stored under, and the file path to
the document. If a document key
is not provided an auto-generated system key will be used for
the document. Documents cannot be added to
collections that do not already exist. When entering the file
path be sure to include the path and
file extension.
</p>
<section>
<title>Summary:</title>
</section>
<p>
<code>xindice add_document-c
(or context)
-f
(or file path)
[-n
(or key to assign to document)
]
[-v
(or )
]
</code>
</p>
<table>
<tr>
<td>Action:</td>
<td>
<code>add_document</code>
</td>
</tr>
<tr>
<td>Abberviated-Action:</td>
<td>
<code>ad</code>
</td>
</tr>
<tr>
<td>Access Level:</td>
<td>User</td>
</tr>
</table>
<section>
<title>Parameters:</title>
</section>
<ul>
<li>
<code>-c</code> The collection context under which to add
the document
</li>
<li>
<code>-f</code> The complete file path to the document
being added
</li>
<li>
<code>-n</code> The key to assign to the document
</li>
<li>
<code>-v</code> Show verbose output
</li>
</ul>
<section>
<title>Examples:</title>
</section>
<section>
<title>Adding a document to a collection with a key of
"stones"</title>
<source><![CDATA[
xindice add_document -c /db/pebbles -f /tmp/stones.xml -n stones
]]></source>
</section>
<section>
<title>Adding a document to the root collection with an
automatically generated key</title>
<source><![CDATA[
xindice add_document -c /db -f /tmp/bookmarks.xml
]]></source>
</section>
</section>
<section>
<title>Adding Multiple Documents</title>
<p>
Adds multiple documents to a collection or a nested
collection. This command requires two arguments: the
collection to store the documents under and the directory path
containing the documents. Documents can be added
to collections as well as subcollections as long as they
exist. Documents added will be assigned their file name
as the document key. The optional "extension" parameter can
be used to import documents with a certain file extension.
Document keys are shown as they are created.
</p>
<section>
<title>Summary:</title>
</section>
<p>
<code>xindice add_multiple_documents-c
(or context)
-f
(or Directory to use )
[-e
(or file extenstion )
]
[-v
(or )
]
</code>
</p>
<table>
<tr>
<td>Action:</td>
<td>
<code>add_multiple_documents</code>
</td>
</tr>
<tr>
<td>Abberviated-Action:</td>
<td>
<code>addmultiple</code>
</td>
</tr>
<tr>
<td>Access Level:</td>
<td>User</td>
</tr>
</table>
<section>
<title>Parameters:</title>
</section>
<ul>
<li>
<code>-c</code> The collection context under which to add
the documents
</li>
<li>
<code>-f</code> The path to the directory to import
documents from
</li>
<li>
<code>-e</code> The file extension to use when importing
documents
</li>
<li>
<code>-v</code> Show verbose output
</li>
</ul>
<section>
<title>Examples:</title>
</section>
<section>
<title>Adding all files from a directory to a
collection</title>
<source><![CDATA[
xindice add_multiple_documents -c /db/pebbles -f /tmp/mydocs
]]></source>
</section>
<section>
<title>Adding all files from a directory with an extension of
".xml" </title>
<source><![CDATA[
xindice add_multiple_documents -c /db/pebbles -f /tmp/mydocs -e xml
]]></source>
</section>
</section>
<section>
<title>Deleting a Document</title>
<p>
Deletes an existing document from a collection or nested
collection within the database.
</p>
<section>
<title>Summary:</title>
</section>
<p>
<code>xindice delete_document-c
(or context)
-n
(or document key)
[-v
(or )
]
</code>
</p>
<table>
<tr>
<td>Action:</td>
<td>
<code>delete_document</code>
</td>
</tr>
<tr>
<td>Abberviated-Action:</td>
<td>
<code>dd</code>
</td>
</tr>
<tr>
<td>Access Level:</td>
<td>User</td>
</tr>
</table>
<section>
<title>Parameters:</title>
</section>
<ul>
<li>
<code>-c</code> The collection context under which to
delete the document
</li>
<li>
<code>-n</code> The key of the document to be deleted
</li>
<li>
<code>-v</code> Show verbose output
</li>
</ul>
<section>
<title>Examples:</title>
</section>
<section>
<title>Deleting a Document from a collection</title>
<source><![CDATA[
xindice delete_document -c /db/pebbles -n stones
]]></source>
</section>
</section>
<section>
<title>Retrieving a Document</title>
<p>
Retrieves an existing document from a collection or nested
collection within the database. The complete path where
the document will be stored is required. If the file path
passed in does not exist, it will be created .
If the file argument given already exists, it will be
overwritten automatically.
</p>
<section>
<title>Summary:</title>
</section>
<p>
<code>xindice retrieve_document-c
(or context)
-n
(or document key)
-f
(or file path and name )
[-v
(or )
]
</code>
</p>
<table>
<tr>
<td>Action:</td>
<td>
<code>retrieve_document</code>
</td>
</tr>
<tr>
<td>Abberviated-Action:</td>
<td>
<code>rd</code>
</td>
</tr>
<tr>
<td>Access Level:</td>
<td>User</td>
</tr>
</table>
<section>
<title>Parameters:</title>
</section>
<ul>
<li>
<code>-c</code> The collection context under which to
retrieve the document
</li>
<li>
<code>-n</code> The key of the document to be retrieved
</li>
<li>
<code>-f</code> The file path to store the document under
</li>
<li>
<code>-v</code> Show verbose output
</li>
<li>
<code>-u</code> The URI for the Xindice host to use.
http://host:[port]
</li>
</ul>
<section>
<title>Examples:</title>
</section>
<section>
<title>Retrieving a document from a collection</title>
<source><![CDATA[
xindice retrieve_document -c /db/pebbles -n stones -f /tmp/stones.xml
]]></source>
</section>
</section>
<section>
<title>Importing a Directory Tree</title>
<p>
Adds multiple documents into a collection or a nested
collection within the database, copying the directory structure into
the database as collections. This command is designed to take
a directory and create a collection from it's name.
Directories under the directory will also be created as
collections, duplicating the directory tree. The files within the
specified directory are converted into Documents and then
stored into the newly created collection with their filenames
as the document keys. The optional "extension" parameter can
be used to only import documents with a certain file extension.
If the collection name used already exists it will be
overwritten. Collection and document keys will are shown as they are created.
</p>
<section>
<title>Summary:</title>
</section>
<p>
<code>xindice import-c
(or context)
-f
(or file path and name )
[-e
(or file extenstion )
]
[-v
(or )
]
</code>
</p>
<table>
<tr>
<td>Action:</td>
<td>
<code>import</code>
</td>
</tr>
<tr>
<td>Abberviated-Action:</td>
<td>
<code>import</code>
</td>
</tr>
<tr>
<td>Access Level:</td>
<td>Admin</td>
</tr>
</table>
<section>
<title>Parameters:</title>
</section>
<ul>
<li>
<code>-c</code> The collection context under which to
import the documents
</li>
<li>
<code>-f</code> The path to the documents being added
</li>
<li>
<code>-e</code> The file extension to use when importing
documents
</li>
<li>
<code>-v</code> Show verbose output
</li>
</ul>
<section>
<title>Examples:</title>
</section>
<section>
<title>Importing all directories and documents</title>
<source><![CDATA[
xindice import -c /db/pebbles -f /tmp/flintstones
]]></source>
</section>
<section>
<title>Importing all directories and documents with an
extension of ".xml" </title>
<source><![CDATA[
xindice import -c /db/pebbles -f /tmp/flintstones -e xml
]]></source>
</section>
</section>
<section>
<title>Exporting a Directory Tree</title>
<p>
Creates an identical directory tree from a collection
including any subcollections.
The directory tree will be created starting at the directory
passed in as an argument.
This command requires the collection which you are eporting
and the directory to export to as arguments.
</p>
<section>
<title>Summary:</title>
</section>
<p>
<code>xindice export-c
(or context)
-f
(or directory path)
[-v
(or )
]
</code>
</p>
<table>
<tr>
<td>Action:</td>
<td>
<code>export</code>
</td>
</tr>
<tr>
<td>Abberviated-Action:</td>
<td>
<code>export</code>
</td>
</tr>
<tr>
<td>Access Level:</td>
<td>User</td>
</tr>
</table>
<section>
<title>Parameters:</title>
</section>
<ul>
<li>
<code>-c</code> The collection context under which to
export the document tree
</li>
<li>
<code>-f</code> The directory to create the collection
structure under
</li>
<li>
<code>-v</code> Show verbose output
</li>
</ul>
<section>
<title>Examples:</title>
</section>
<section>
<title>Creating a directory tree indentical to a
collection</title>
<source><![CDATA[
xindice export -c /db/pebbles -f /tmp/pebbles
]]></source>
</section>
</section>
</section>
<!--chapter>
<docinfo>
<title>XMLObject Management Actions</title>
</docinfo>
<sect1>
<title>Adding a XMLObject</title>
<para>
Adds a new XMLObject or nested XMLObject to the database. Adding an
XMLObject requires
an implementing class and a name. In order to add the XMLObject the
collection that it is being added
to must already exist. to sucessfully complete this topertation, the
implementing class must be in the server's classpath.
</para>
<bridgehead renderas="sect2">Summary:</bridgehead>
<cmdsynopsis>
<command>xindice add_xmlobject</command>
<arg choice="req">-c <replaceable>context</replaceable></arg>
<arg choice="req">-i <replaceable>implementing class</replaceable></arg>
<arg choice="req">-n <replaceable>object name </replaceable></arg>
<arg choice="opt">-v <replaceable></replaceable></arg>
</cmdsynopsis>
<informaltable frame="none">
<tgroup cols="2">
<tbody>
<row><entry>Action:</entry><entry><command>add_xmlobject
</command></entry></row>
<row><entry>Abberviated-Action:</entry><entry><command>ao
</command></entry></row>
<row><entry>Access Level:</entry><entry>Admin </entry></row>
</tbody>
</tgroup>
</informaltable>
<bridgehead renderas="sect2">Parameters:</bridgehead>
<simplelist>
<member>
<command>-c</command> The collection context under which to add the
XMLObject
</member>
<member>
<command>-i</command> The fully qualified class name for the
implementing class
</member>
<member>
<command>-n</command> The name to assign to the XMLObject
</member>
<member>
<command>-v</command> Show verbose output
</member>
</simplelist>
<bridgehead renderas="sect2">Examples:</bridgehead>
<example>
<title>Create a XMLObject in the pebbles collection </title>
<screen>
xindice add_xmlobject -c /db/pebbles -i example.XmlRockObject -n
rockXMLObject
</screen>
</example>
<example>
<title>Create a XMLObject in a sub collection</title>
<screen>
xindice add_xmlobject -c /db/pebbles/boulder -i
example.XmlRockObject -n rockXMLObject
</screen>
</example>
</sect1>
<sect1>
<title>Deleting a XMLObject</title>
<para>
Deletes an XMLObject or nested XMLObject from the database. Deleting
an XMLObject requires the collection name and the
XMLObject name.
</para>
<bridgehead renderas="sect2">Summary:</bridgehead>
<cmdsynopsis>
<command>xindice delete_xmlobject</command>
<arg choice="req">-c <replaceable>context</replaceable></arg>
<arg choice="req">-n <replaceable>name </replaceable></arg>
<arg choice="opt">-v <replaceable></replaceable></arg>
</cmdsynopsis>
<informaltable frame="none">
<tgroup cols="2">
<tbody>
<row><entry>Action:</entry><entry><command>delete_xmlobject
</command></entry></row>
<row><entry>Abberviated-Action:</entry><entry><command>do
</command></entry></row>
<row><entry>Access Level:</entry><entry>Admin </entry></row>
</tbody>
</tgroup>
</informaltable>
<bridgehead renderas="sect2">Parameters:</bridgehead>
<simplelist>
<member>
<command>-c</command> The collection context under which to delete
the XMLObject
</member>
<member>
<command>-n</command> The name of the XMLObject to delete
</member>
<member>
<command>-v</command> Show verbose output
</member>
</simplelist>
<bridgehead renderas="sect2">Examples:</bridgehead>
<example>
<title>Delete an XMLObject in the pebbles collection </title>
<screen>
xindice delete_xmlobject -c /db/pebbles -n rockXMLObject
</screen>
</example>
<example>
<title>Delete an XMLObject from the boulder sub collection</title>
<screen>
xindice delete_xmlobject -c /db/pebbles/boulder -n rockXMLObject
</screen>
</example>
</sect1>
<sect1>
<title>Listing XMLObjects</title>
<para>
Lists all XMLObjects or nested XMLObjects in the database. The listing
of XMLObjects works in a similar fashion to
listing collections.
</para>
<bridgehead renderas="sect2">Summary:</bridgehead>
<cmdsynopsis>
<command>xindice lists_xmlobjects</command>
<arg choice="req">-c <replaceable>context</replaceable></arg>
<arg choice="opt">-v <replaceable></replaceable></arg>
</cmdsynopsis>
<informaltable frame="none">
<tgroup cols="2">
<tbody>
<row><entry>Action:</entry><entry><command>list_xmlobjects
</command></entry></row>
<row><entry>Abberviated-Action:</entry><entry><command>lo
</command></entry></row>
<row><entry>Access Level:</entry><entry>User </entry></row>
</tbody>
</tgroup>
</informaltable>
<bridgehead renderas="sect2">Parameters:</bridgehead>
<simplelist>
<member>
<command>-c</command> The collection context under which to list the
XMLObjects
</member>
<member>
<command>-v</command> Show verbose output
</member>
</simplelist>
<bridgehead renderas="sect2">Examples:</bridgehead>
<example>
<title>List all XMLObjects in the pebbles collection </title>
<screen>
xindice list_xmlobjects -c /db/pebbles
</screen>
</example>
<example>
<title>List all XMLObjects in the boulder sub collection</title>
<screen>
xindice list_xmlobjects -c /db/pebbles/boulder
</screen>
</example>
</sect1>
<sect1>
<title>Invoke an XMLObject</title>
<para>
Allows the invocation of an XMLObject in the database.
This command requires two arguments - the collection
to invoke the object under and the URI for the XMLObject.
The URI given can be either relative or the absolute path.
(See the users guide for more information on URI's)
</para>
<bridgehead renderas="sect2">Summary:</bridgehead>
<cmdsynopsis>
<command>xindice invoke</command>
<arg choice="req">-c <replaceable>context</replaceable></arg>
<arg choice="req">-o <replaceable>object URI</replaceable></arg>
<arg choice="opt">-v <replaceable></replaceable></arg>
</cmdsynopsis>
<informaltable frame="none">
<tgroup cols="2">
<tbody>
<row><entry>Action:</entry><entry><command>invoke
</command></entry></row>
<row><entry>Abberviated-Action:</entry><entry><command>invoke
</command></entry></row>
<row><entry>Access Level:</entry><entry>User </entry></row>
</tbody>
</tgroup>
</informaltable>
<bridgehead renderas="sect2">Parameters:</bridgehead>
<simplelist>
<member>
<command>-c</command> The collection context under which to invoke
the XMLObject
</member>
<member>
<command>-o</command> The XMLObject that is being invoked
</member>
<member>
<command>-v</command> Show verbose output
</member>
</simplelist>
<bridgehead renderas="sect2">Examples:</bridgehead>
<example>
<title> Invoke the rockXMLObject in the pebbles collection</title>
<screen>
xindice invoke -c /db/pebbles -o rockXMLObject
</screen>
</example>
<example>
<title>
Invoke a rockXMLObject with a method named crush that takes a
name parameter named rock
</title>
<screen>
xindice invoke -c /db/pebbles -o rockXMLObject/crush?rock=boulder
</screen>
</example>
</sect1>
</chapter-->
<section>
<title>Collection Indexer Actions</title>
<section>
<title>Adding a Collection Indexer</title>
<p>
Adds a new collection index or nested collection index to the
database. In order to add the collection index,
the collection it is being added to must already exist. This
command allows you to supply optional parameters
for setting the index page size, setting the maximum key size
for the index, and the index data type.
</p>
<section>
<title>Summary:</title>
</section>
<p>
<code>xindice add_indexer-c
(or context)
-n
(or index name )
-p
(or index pattern)
[--pagesize
(or pagesize)
]
[--maxkeysize
(or max key size)
]
[-t
(or index type)
]
[-v
(or )
]
</code>
</p>
<table>
<tr>
<td>Action:</td>
<td>
<code>add_indexer</code>
</td>
</tr>
<tr>
<td>Abberviated-Action:</td>
<td>
<code>ai</code>
</td>
</tr>
<tr>
<td>Access Level:</td>
<td>Admin</td>
</tr>
</table>
<section>
<title>Parameters:</title>
</section>
<ul>
<li>
<code>-c</code> The collection context under which to add
the indexer
</li>
<li>
<code>-n</code> The name of the index being added
</li>
<li>
<code>-p</code> The pattern used to create the index
</li>
<li>
<code>--maxkeysize</code> The MaxKeySize for the index (
default: 0 = none )
</li>
<li>
<code>--pagesize</code> The PageSize for the index (
default: 4096)
</li>
<li>
<code>-t</code>
The data type for the index to create. Possible values are:
<code><![CDATA[ string Non-normalized string value
trimmed Normalized (whitespace stripped) string value
short 16-bit signed short integer
int 32-bit signed integer
long 64-bit signed integer
float 32-bit floating point value
double 64-bit floating point value (XPath number)
byte 8-bit signed byte
char 16-bit signed character
boolean 8-bit boolean value
name Store document keys that contain the
pattern]]></code>
</li>
<li>
<code>-v</code> Show verbose output
</li>
</ul>
<section>
<title>Examples:</title>
</section>
<section>
<title>To create a collection index in the pebbles collection
for docuemnts with a "rock" element</title>
<source><![CDATA[
xindice add_indexer -c /db/pebbles -n rockindex -p rock
]]></source>
</section>
<section>
<title>To create a collection index in the boulder sub
collection for documents containing a rock elements with an attribute of
"hard"</title>
<source><![CDATA[
xindice add_indexer -c /db/pebbles/boulder -n hardindex -p [EMAIL PROTECTED]
]]></source>
</section>
</section>
<section>
<title>Deleting a Collection Indexer</title>
<p>
Deletes a collection index or a nested collection index from
the database. Deleting an index requires the collection and index name.
If a collection index is deleted, the collection will still
remain.
</p>
<section>
<title>Summary:</title>
</section>
<p>
<code>xindice delete_indexer-c
(or context)
-n
(or index name)
[-v
(or )
]
</code>
</p>
<table>
<tr>
<td>Action:</td>
<td>
<code>delete_indexer </code>
</td>
</tr>
<tr>
<td>Abberviated-Action:</td>
<td>
<code>di </code>
</td>
</tr>
<tr>
<td>Access Level:</td>
<td>Admin </td>
</tr>
</table>
<section>
<title>Parameters:</title>
</section>
<ul>
<li>
<code>-c</code> The collection context under which to
delete the index
</li>
<li>
<code>-n</code> The name of the indexer being deleted
</li>
<li>
<code>-v</code> Show verbose output
</li>
</ul>
<section>
<title>Examples:</title>
</section>
<section>
<title>Delete a collecion index in the pebbles
collection</title>
<source><![CDATA[
xindice delete_indexer -c /db/pebbles -n hardindex
]]></source>
</section>
</section>
<section>
<title>Listing Collection Indexers</title>
<p>
Lists all collection indexers or nested collection indexes in
the database. The listing of indexes works
in a similar fashion to listing collections
</p>
<section>
<title>Summary:</title>
</section>
<p>
<code>xindice list_indexers-c
(or context)
[-v
(or )
]
</code>
</p>
<table>
<tr>
<td>Action:</td>
<td>
<code>list_indexers</code>
</td>
</tr>
<tr>
<td>Abberviated-Action:</td>
<td>
<code>li</code>
</td>
</tr>
<tr>
<td>Access Level:</td>
<td>Admin</td>
</tr>
</table>
<section>
<title>Parameters:</title>
</section>
<ul>
<li>
<code>-c</code> The collection context under which to list
the indexers
</li>
<li>
<code>-v</code> Show verbose output
</li>
</ul>
<section>
<title>Examples:</title>
</section>
<section>
<title>To list all collection indexes from the pebbles
collection </title>
<source><![CDATA[
xindice list_indexers -c /db/pebbles
]]></source>
</section>
</section>
</section>
<section>
<title>Xpath Query Actions</title>
<section>
<title>Executing an Xpath Query against a Collection</title>
<p>
Execute an Xpath query against a collection or nested
collection. The command requires two arguments : the collection to
query against and the query string to use.
</p>
<section>
<title>Summary:</title>
</section>
<p>
<code>xindice xpath-c
(or context)
-q
(or query)
-s
(or prefix=namespace)
[-v
(or )
]
</code>
</p>
<table>
<tr>
<td>Action:</td>
<td>
<code>xpath</code>
</td>
</tr>
<tr>
<td>Abberviated-Action:</td>
<td>
<code>xpath</code>
</td>
</tr>
<tr>
<td>Access Level:</td>
<td>User</td>
</tr>
</table>
<section>
<title>Parameters:</title>
</section>
<ul>
<li>
<code>-c</code> The collection context under which to
execute the query
</li>
<li>
<code>-q</code> The query to execute against the collection
</li>
<li>
<code>-s</code> Semi-colon delimited list of namespaces for
query in the form prefix=namespace-uri
</li>
<li>
<code>-v</code> Show verbose output
</li>
</ul>
<section>
<title>Examples:</title>
</section>
<section>
<title>
Run an Xpath query against all documents in the pebbles
collection with "rock" node that has the type
attribute = "hard"
</title>
<source><![CDATA[
xindice xpath -c /db/pebbles -q /[EMAIL PROTECTED]"hard"]
]]></source>
</section>
<section>
<title>
Run an Xpath query against all documents in the pebbles
collection with "rock" node that has the type
attribute = "hard" when the rock element is in the
namespace http://www.bedrock.com
</title>
<source><![CDATA[
xindice xpath -c /db/pebbles -s "br=http://www.bedrock.com" -q /br:[EMAIL
PROTECTED]"hard"]
]]></source>
</section>
</section>
</section>
<section>
<title>Miscellaneous Actions</title>
<section>
<title>Shutting down the server</title>
<p>
Shutdown the Xindice server
</p>
<section>
<title>Summary:</title>
</section>
<p>
<code>xindice shutdown
[-v
(or )
]
</code>
</p>
<table>
<tr>
<td>Action:</td>
<td>
<code>shutdown</code>
</td>
</tr>
<tr>
<td>Abberviated-Action:</td>
<td>
<code>shutdown</code>
</td>
</tr>
<tr>
<td>Access Level:</td>
<td>Admin</td>
</tr>
</table>
<section>
<title>Parameters:</title>
</section>
<ul>
<li>
<code>-v</code> Show verbose output
</li>
</ul>
<section>
<title>Examples:</title>
</section>
<section>
<title>Shutdown the server </title>
<source><![CDATA[
xindice shutdown
]]></source>
</section>
</section>
<section>
<title>Accessing online Help</title>
<p>
Show the online help
</p>
<section>
<title>Summary:</title>
</section>
<p>
<code>xindice help
[-v
(or )
]
</code>
</p>
<table>
<tr>
<td>Action:</td>
<td>
<code>help</code>
</td>
</tr>
<tr>
<td>Abberviated-Action:</td>
<td>
<code>help</code>
</td>
</tr>
<tr>
<td>Access Level:</td>
<td>User</td>
</tr>
</table>
<section>
<title>Parameters:</title>
</section>
<ul>
<li>
<code>-v</code> Show verbose output
</li>
</ul>
<section>
<title>Examples:</title>
</section>
<section>
<title>Show online Help</title>
<source><![CDATA[
xindice help
]]></source>
</section>
</section>
</section>
</body>
</document>
1.1
xml-xindice/src/documentation/content/xdocs/dev/guide-developer.xml
Index: guide-developer.xml
===================================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN"
"document-v11.dtd">
<!--
- Version: $Revision: 1.1 $ $Date: 2002/11/17 08:16:03 $
- Author: Kimbro Staken ([EMAIL PROTECTED])
-->
<document>
<header>
<title>Developer Guide</title>
<authors>
<person id="ks" name="Kimbro Staken" email=""/>
</authors>
<notice/>
<abstract/>
</header>
<body>
<warning>This documentation is a work in progress and is only
applicable to the CVS version of Xindice. There is absolutely no guarantee that
this information is accurate. You have been warned.
</warning>
<section>
<title>Introduction to Programming Xindice</title>
<section>
<title>Accessing the Server</title>
<p>
The Xindice server can be accessed either programmatically
through
the server's APIs or from the command line using the provided
command line tools. This document covers programmatic access,
for more information on using the command
line interface please refer to the
<link href="guide-user.html">Xindice Users Guide</link>.
</p>
<section>
<title>API's</title>
<p>
Xindice currently offers three layers of APIs that can be
used to
develop applications.
</p>
<ul>
<li>
XML:DB XML Database API used to develop Xindice
applications
in Java. This is the primary API used to develop
applications and will be the API given the most coverage
in
this manual. The XML:DB API is built on top of the
Xindice
CORBA API. Xindice currently implements the May 07, 2001
draft
of the XML:DB API. This API will change slightly in the
future to track the development of the XML:DB API.
</li>
<li>
CORBA API used when accessing Xindice from a language
other
then Java. The CORBA API is built on top of the Core
Server
API. It is likely that the CORBA API will be replaced
with a
new network API in a later version of Xindice.
</li>
<li>
Core Server API is the internal Java API of the core
database engine. This API is used to build the CORBA API
and
is also used when writing XMLObject server extensions.
This is
the lowest level API and is only available to software
running
in the same Java VM as the database engine itself. the
most
common use of this API is in developing XMLObject server
extensions.
</li>
</ul>
</section>
<p>
The most common API for end user
applications is the XML:DB XML Database API that was developed
by the
<link href="http://www.xmldb.org">XML:DB Initiative</link>.
This API is
a vendor neutral API intended to make it possible to build
applications that will work with more then one XML database
without too much difficulty. This is similar to the
capabilities provided by JDBC for relational databases. More
information about this
API can be found on the XML:DB Initiative web site.
<link href="http://www.xmldb.org/">http://www.xmldb.org</link>
Most
programming examples in this manual will use the XML:DB API.
The
Xindice implementation of the API is a Core Level 1
implementation.
</p>
<p>
The Xindice server also exposes a CORBA API that is used to
implement the XML:DB API. The CORBA API will mainly be of
interest to those who want to access Xindice from a language
other
then Java. Any language that supports a CORBA binding should be
able to utilize the services of the Xindice server via the
CORBA
API. This document
does not cover development with the CORBA API as the XML:DB API
is the preferred mechanism for developing Xindice
applications. If
you are developing applications in Java you can safely ignore
the
existence of this API. The CORBA API will be covered in a
seperate document to be written at a later time.
</p>
<p>
The final API for Xindice is the Core Server API. <!-- that
is used when
writing XMLObject server extensions. This API is the lowest
level
API available for the Xindice server and will be covered
briefly
when looking at the development of XMLObjects.
-->
</p>
</section>
<section>
<title>Introducing the XML:DB XML Database API</title>
<p>
XML:DB API is being developed by the
<link href="http://www.xmldb.org">XML:DB Initiative</link> to
facilitate the development of applications that function with
minimal change on more then one XML database.
This is roughly
equivalent to the functionality provided by JDBC or ODBC for
providing access to relational databases. Xindice provides an
implementation of the XML:DB API that also serves as the
primary
programming API for Xindice.
</p>
<p>
The XML:DB API is based around the concept of collections that
store
resources. A resource can be an XML Document, a binary blob or
some type that is not currently defined. Collections can be
arranged
in a hierarchical fashion. This makes the architecture very
similar
to that of a typical Windows or UNIX file system. What is
different
however, is that collections also expose services that allow
you to
do things such as query XML documents using XPath or update
resources in a
transactionally secure manner.
</p>
<p>
The XML:DB API defines several levels of interoperability
called
Core Levels in XML:DB terminology. The Xindice implementation
of the
API is a Core Level 1 implementation plus implementations of
some
of the optional services.
</p>
<p>
The additional supported services include.</p>
<ul>
<li>
XUpdateQueryService - Enables execution of XUpdate queries
against the database.
</li>
<li>
CollectionManagementService - Provides basic facilities to
create and remove collections.
</li>
</ul>
<p>
In addition to Core Level 1 support the Xindice implementation
also
supports a few added services that are specific to Xindice.
These
services exist because the functionality is necessary to fully
utilize all the capabilities provided by Xindice. However,
they are
proprietary to Xindice and will not function unchanged on
other XML
databases.
</p>
<p>
The following services are currently provided by Xindice and
are not
part of the common XML:DB API.
</p>
<ul>
<li>
DatabaseInstanceManager - Provides the ability to control
the
operation of the server programatically.
</li>
<li>
CollectionManager - Provides the ability to create and
configure collection instances within the server. This is a
much more functional version of CollectionManagementService
that will only work with Xindice.
</li>
<!--
<li>
XMLObjectService - Provides a mechanism to invoke
XMLObjects
within the server.
</li>
-->
</ul>
<p>
While this guide aims to provide some useful examples and to
guide
you in the process of getting to know how to program Xindice
it is
also
useful to know that there is a good source of example code
within
the server it self. The Xindice command line tools are built
100% on
the XML:DB API and provide a pretty comprehensive set of
examples in how to use the API. This is especially true when it
comes to the Xindice
specific services that are included with the server. The
source code
for all the command line tools can be found in
<code>Xindice/java/src/org/apache/xindice/tools/command</code>.
</p>
</section>
<section>
<title>Setting up Your Build Environment</title>
<p>
Before you can build applications for Xindice you need to make
sure you
have your build environment properly setup. This mainly
consists of
making sure that you have the proper VM version and a properly
configured
<code>CLASSPATH</code>.
</p>
<p>
To build applications for Xindice you must be using JDK 1.3.
At this time
there appear to be problems with JDK 1.4. JDK 1.2 and below
will not
work at all. If you have more than one Java VM installed make
sure that
your
<code>JAVA_HOME</code> environment variable and
<code>PATH</code> environment variable both include the correct
path.
</p>
<p>
Once you have your Java VM properly configured you need to add
a few
jar files to your
<code>CLASSPATH</code>. The following list of
jars are required and should be made available on your
<code>CLASSPATH</code>. All required jars can be found in
<code>Xindice/java/lib</code>
</p>
<ul>
<li>
xindice.jar - contains the main Xindice classes that are
used by
the client API.
</li>
<li>
xmldb.jar - contains the XML:DB API interfaces.
</li>
<li>
openorb-1.2.0.jar - contains the CORBA ORB implementation
used
by the client API to communicate with the server.
</li>
<li>
xerces-1.4.3.jar - contains the Xerces XML parser.
</li>
<li>
xalan-2.0.1.jar - contains the Xalan XSL-T engine. This
jar isn't absolutely required but you'll probably want it so
it's worth adding it.
</li>
</ul>
</section>
<section>
<title>Preparing the Server For the Examples</title>
<p>
Before we get to some example code, we need to do a little
work to setup the
server. Don't worry nothing hard.
</p>
<p>
First we need to make sure the addressbook collection exists.
If you followed
the install instructions completely you should have already
created this,
but if not you should do so now. To find out if the collection
exists you
can run:
</p>
<source><![CDATA[xindice lc -c /db]]></source>
<p>
If you don't see 'addressbook' listed in the result then you
need to create
the collection. To create it just run:
</p>
<source><![CDATA[xindice ac -c /db -n addressbook]]></source>
<p>
Now that we have the collection, we can add a few example
documents
so that we have something to play with. You can find the
examples in your
Xindice installation in the directory
<code>java/examples/guide/xml</code>. Run these commands to add
the documents.
</p>
<source><![CDATA[
cd $XINDICE_HOME/java/examples/guide/xml
xindice ad -c /db/addressbook -f address1.xml -n address1
xindice ad -c /db/addressbook -f address2.xml -n address2
]]></source>
<p>
If you're on Windows you'll need to adjust the path in the cd
command
for your platform. Most of the examples in the manual will be
written for
UNIX but will work fine in Windows if you just replace / with
\ and
$XINDICE_HOME with %XINDICE_HOME%.
</p>
<p>
That wasn't so bad and now we're set to look at some example
code.
</p>
</section>
<section>
<title>Diving in With an Example Program</title>
<section>
<title>Simple XML:DB Example Program</title>
<p>This example simply executes an XPath query against a
collection, retrieves the results as text and prints them
out.
</p>
<p>
You can find the source code for this example in
Xindice/java/examples/guide/src/org/apache/xindice/examples/Example1.java
</p>
<source><![CDATA[package org.apache.xindice.examples;
import org.xmldb.api.base.*;
import org.xmldb.api.modules.*;
import org.xmldb.api.*;
public class Example1 {
public static void main(String[] args) throws Exception {
Collection col = null;
try {
String driver = "org.apache.xindice.client.xmldb.DatabaseImpl";
Class c = Class.forName(driver);
Database database = (Database) c.newInstance();
DatabaseManager.registerDatabase(database);
col = DatabaseManager.getCollection("xmldb:xindice:///db/addressbook");
String xpath = "//person[fname='John']";
XPathQueryService service =
(XPathQueryService) col.getService("XPathQueryService", "1.0");
ResourceSet resultSet = service.query(xpath);
ResourceIterator results = resultSet.getIterator();
while (results.hasMoreResources()) {
Resource res = results.nextResource();
System.out.println((String) res.getContent());
}
}
catch (XMLDBException e) {
System.err.println("XML:DB Exception occured " + e.errorCode);
}
finally {
if (col != null) {
col.close();
}
}
}
}]]></source>
</section>
<p>
Before diving into the gory detail of what this program is
doing, let's
run it and see what we get back.
</p>
<p>
If you have a binary build of Xindice the examples are already
built
and you can run this example by typing.
</p>
<source><![CDATA[
cd $XINDICE_HOME/java/examples/guide
./run org.apache.xindice.examples.Example1
]]></source>
<p>
If all goes well, you should see a result that looks something
like this.
</p>
<source><![CDATA[<?xml version="1.0"?>
<person xmlns:src="http://xml.apache.org/xindice/Query"
src:col="/db/addressbook" src:key="address1">
<fname>John</fname>
<lname>Smith</lname>
<phone type="work">563-456-7890</phone>
<phone type="home">534-567-8901</phone>
<email type="home">[EMAIL PROTECTED]</email>
<email type="work">[EMAIL PROTECTED]</email>
<address type="home">34 S. Colon St.</address>
<address type="work">9967 W. Shrimp Ave.</address>
</person>]]></source>
<p>
Now that we've seen the result, let's dive in and look at the
code in
detail.
While this isn't the simplest possible example program to
start with
it does a nice job of showing all the basic techniques used
when
building applications with the XML:DB API.
</p>
<p>
To begin the program imports several XML:DB packages.
</p>
<source><![CDATA[
import org.xmldb.api.base.*;
import org.xmldb.api.modules.*;
import org.xmldb.api.*;
]]></source>
<p>
These import the basic classes required by the API.
<code>import org.xmldb.api.base.*;</code> is the base API
module
and is required for all XML:DB applications.
<code>import org.xmldb.api.*;</code> imports the all
important
<code>DatabaseManager</code> class which is the
entry point into the API.
<code>import org.xmldb.api.modules.*;</code> brings in the
optional modules defined for the API. In this case the module
we're
interested in is
<code>XPathQueryService</code>.
</p>
<p>
Before we can use the API we need to create and register the
database driver we want to use. In this case since we're
writing for
Xindice we use
<code>org.apache.xindice.client.xmldb.DatabaseImpl</code>
for our driver and register it with the
<code>DatabaseManager</code>
</p>
<source><![CDATA[
String driver = "org.apache.xindice.client.xmldb.DatabaseImpl";
Class c = Class.forName(driver);
Database database = (Database) c.newInstance();
DatabaseManager.registerDatabase(database);
]]></source>
<p>
Now that our driver is registered we're ready to retrieve the
collection that we want to work with.
</p>
<source><![CDATA[
Collection col =
DatabaseManager.getCollection("xmldb:xindice:///db/addressbook");
]]></source>
<p>
In the XML:DB API collections are retrieved
by calling
<code>getCollection</code> and
handing it a URI that specifies the collection we want. The
format
of this URI will vary depending on the database implementation
being
used but will always begin with
<code>xmldb:</code> and be followed by a database
specific database name,
<code>xindice:</code> in
the case of Xindice.
</p>
<p>
The rest of the URI is a path used to locate the collection
you want
to work with. This path begins with the name of the root
collection
for the Xindice instance that you are trying to connect with.
All
Xindice instances must have a unique name for the root
collection. The
reason for this is that the name of the root collection is
also the
name of the database instance and that name is what the
Xindice server
uses to register itself with the naming service. In all
examples in
this guide the root collection is called
<code>db</code>. This
is the default name used for a newly installed instance of
Xindice. If
you have more then one instance of Xindice running that you
must be
sure to change the names on all other instances so that they
are
unique.
Once you do this you can switch between the instances by simply
changing the first component of the path.
</p>
<source><![CDATA[
xindice:///db/news
xindice:///db2/news
]]></source>
<p>
These paths will switch between a Xindice server
with a root collection of db and one of db2. These instances
could
be on the same machine or on two completely different machines
and
to your application there is no significant difference.
</p>
<p>
After the root collection name the rest of the URI
simply consists of the path to locate the collection you want
to work with.
</p>
<p>
Now that we have a reference to the collection that we want to
work
with we need to get a reference to the
<code>XPathQueryService</code>
service for that collection.
</p>
<source><![CDATA[
String xpath = "//person[fname='John']";
XPathQueryService service =
(XPathQueryService) col.getService("XPathQueryService", "1.0");
ResourceSet resultSet = service.query(xpath);
]]></source>
<p>
Services provide a way to extend the
functionality of the XML:DB API as well as enabling the
definition
of optional functionality. In this case the
<code>XPathQueryService</code> is an optional part of Core
Level 0 but is a required part of Core Level 1. Since Xindice
provides a Core Level 1 XML:DB API implementation the
<code>XPathQueryService</code> is available.
</p>
<p>
To retrieve a service you must know the name of the service
that
you want as well as the version. Services define their own
custom
interfaces so you must cast the result of the getService()
call to
the appropriate service type before you can call its methods.
The
<code>XPathQueryService</code> defines a method
<code>query()</code> that takes an XPath string as an argument.
Different services will define different sets of methods.
</p>
<p>
Now that we have an
<code>XPathQueryService</code> reference
and have called the
<code>query()</code> method we get a
<code>ResourceSet</code> containing the results. Since we just
want to print out the results of the query, we need to get an
iterator for our results and then use it to print out the
results.
</p>
<source><![CDATA[
ResourceIterator results = resultSet.getIterator();
while (results.hasMoreResources()) {
Resource res = results.nextResource();
System.out.println((String) res.getContent());
}
]]></source>
<p>
Resources are another important concept within the XML:DB API.
Since
XML can be accessed with multiple APIs and since an XML
database
could potentialy store more the one type of data, resources
provide
an abstract way to access the data in the database. The Xindice
implementation only supports XMLResource but other vendors may
support additional resource types as well.
</p>
<p>
XMLResource provides access to the underlying XML data as
either
text, a DOM Node or via SAX ContentHandlers. In our example
we're
simply working with the content as text but we could just as
easily
have called
<code>getContentAsDom()</code> to get the content
as a DOM Node. Since we just want to print the XML out to the
screen
it is easier to just work with text.
</p>
<p>
The final element about our example program worth noting is the
finally clause.
</p>
<source><![CDATA[
finally {
if (col != null) {
col.close();
}
}
]]></source>
<p>
The finally clause closes the collection that we created
earlier.
This is vitally important and should never be overlooked.
Closing
the collection releases all the resources consumed by the
collection. In the Xindice implementation this will make sure
that the
CORBA resources are released properly. Failure to properly call
close on the collection will result in a
resource leak within the server.
</p>
</section>
<section>
<title>Accessing Xindice Remotely</title>
<p>
By default Xindice assumes that the client and server are
running on
the same machine. In most configurations this will not be the
case
so it will be necessary to include the hostname and port of the
server where Xindice is running in your URIs. The port you use
is the
port that the Xindice HTTP server is listening on. The port
setting is
displayed when you start the server. By default the
configuration used is
<code>xindice://localhost:4080</code>.
To access the collection /db/addressbook on host
xml.apache.org port
4090 the URI would look something like this
<code>xindice://xml.apache.org:4090/db/addressbook</code>. If
you
are running the client and server on the same machine you do
not
need to specify a host or port. All examples in this document
assume
the client and server are on the same machine.
</p>
<p>
If you are having problems accessing Xindice remotely this may
be the
result of the server publishing an incorrect IP address as
part of
its CORBA IOR. The IOR is generated by the ORB using the
hostname
setting of the server. If the hostname is set to a
fully qualified domain name that can not be resolved by the
client
you will not be able to remotely access the server. To fix this
you must insure the host name on the server is resolvable by
the
client. To see the setting of the host name on the server you
should
be able to type
<code>hostname</code> at a command prompt. If
the hostname is not a fully qualified domain name then the ORB
will
use the IP address of the server instead of the name and you
shouldn't have any problems.
</p>
</section>
</section>
<section>
<title>Managing Documents</title>
<p>
In this chapter we'll look at using the XML:DB API to manage
documents
within the Xindice server. As part of this we'll look at some
sample code
that could be used to manage the data used by the AddressBook
example
application included with the server and discussed in more detail
later.
</p>
<p>
When looking at managing documents with the XML:DB API the first
thing
we need to confront is that the API doesn't actually work
directly with
documents. It works with what the API calls resources that are an
abstraction of a document. This abstraction allows you to work
with the same
document as either text, a DOM tree or SAX events. This is
important to
understand as the use of resources runs as a common thread
throughout the
XML:DB API. The XML:DB API actually defines more then one type of
resource
however Xindice does not implement anything beyond XMLResource.
</p>
<section>
<title>Creating a Collection</title>
<p>
Before we can work with any data in the database we need to
create
a collection to hold our data.
While we could easily create this collection using the command
line
tools it will be more fun to see how you might do this from
your own
program. This will also show you a quick example of using the
Xindice
specific
<code>CollectionManager</code> service to manage
collections. This guide doesn't go into detail about using this
service but you can find lots of examples by looking at the
source
code to the command line tool commands in the package
<code>org/apache/xindice/tools/commands</code>.
</p>
<p>
The collection we want to create will be named
<code>mycollection</code> and will be a child of the root
collection.
</p>
<section>
<title>Creating a Collection</title>
<source><![CDATA[package org.apache.xindice.examples;
import org.xmldb.api.base.*;
import org.xmldb.api.modules.*;
import org.xmldb.api.*;
// For the Xindice specific CollectionManager service
import org.apache.xindice.client.xmldb.services.*;
import org.apache.xindice.xml.dom.*;
public class CreateCollection {
public static void main(String[] args) throws Exception {
Collection col = null;
try {
String driver = "org.apache.xindice.client.xmldb.DatabaseImpl";
Class c = Class.forName(driver);
Database database = (Database) c.newInstance();
DatabaseManager.registerDatabase(database);
col =
DatabaseManager.getCollection("xmldb:xindice:///db/");
String collectionName = "mycollection";
CollectionManager service =
(CollectionManager) col.getService("CollectionManager", "1.0");
// Build up the Collection XML configuration.
String collectionConfig =
"<collection compressed=\"true\" name=\"" + collectionName + "\">" +
" <filer class=\"org.apache.xindice.core.filer.BTreeFiler\"
gzip=\"true\"/>" +
"</collection>";
service.createCollection(collectionName,
DOMParser.toDocument(collectionConfig));
System.out.println("Collection " + collectionName + " created.");
}
catch (XMLDBException e) {
System.err.println("XML:DB Exception occured " + e.errorCode);
}
finally {
if (col != null) {
col.close();
}
}
}
}]]></source>
</section>
<p>
With this example you can see a basic example of how to create
the
<code>CollectionManager</code> service and use it to create
the collection. This service is proprietary to Xindice so if
you use
it in your application you will not be able to port it to
another
server. However, if you have the need to create collections
within
your programs this is currently the most powerful way to do it.
</p>
<p>
The trickiest part of creating a collection is creating the
proper XML configuration to hand to the
<code>createCollection</code> method. This XML
is the exact same thing that is placed into the system.xml
file.
At this time these XML configurations are not documented so to
see what they need to be you should look for examples in
system.xml
and the source code for the command line tools. Future
versions of
this documentation will cover this area in more detail.
</p>
</section>
<section>
<title>Working with Documents</title>
<p>
Now that we have a collection to store our data, we need to add
some data to it. We could use the command line tools
to do this but since we want to learn how the XML:DB API works
we'll
look at how we can do this in a program that we write.
</p>
<p>
For our examples in this chapter we'll work with some very
simple
XML files that could be used to represent a person in an
address book. Later in the guide we'll look at an example
application that implements the actual address book
functionality.
Each address book entry is stored in a seperate XML file.
</p>
<section>
<title>Example Document</title>
<source><![CDATA[<person>
<fname>John</fname>
<lname>Smith</lname>
<phone type="work">563-456-7890</phone>
<phone type="home">534-567-8901</phone>
<email type="home">[EMAIL PROTECTED]</email>
<email type="work">[EMAIL PROTECTED]</email>
<address type="home">34 S. Colon St.</address>
<address type="work">9967 W. Shrimp Ave.</address>
</person>]]></source>
</section>
<p>
If we store this example XML into a file we can then load it
into
our addressbook collection using a simple program.
</p>
<section>
<title>Adding an XML File to the Database</title>
<source><![CDATA[package org.apache.xindice.examples;
import org.xmldb.api.base.*;
import org.xmldb.api.modules.*;
import org.xmldb.api.*;
import java.io.*;
public class AddDocument {
public static void main(String[] args) throws Exception {
Collection col = null;
try {
String driver = "org.apache.xindice.client.xmldb.DatabaseImpl";
Class c = Class.forName(driver);
Database database = (Database) c.newInstance();
DatabaseManager.registerDatabase(database);
col =
DatabaseManager.getCollection("xmldb:xindice:///db/addressbook");
String data = readFileFromDisk(args[0]);
XMLResource document = (XMLResource) col.createResource(null,
"XMLResource");
document.setContent(data);
col.storeResource(document);
System.out.println("Document " + args[0] + " inserted");
}
catch (XMLDBException e) {
System.err.println("XML:DB Exception occured " + e.errorCode);
}
finally {
if (col != null) {
col.close();
}
}
}
public static String readFileFromDisk(String fileName) throws Exception {
File file = new File(fileName);
FileInputStream insr = new FileInputStream(file);
byte[] fileBuffer = new byte[(int)file.length()];
insr.read(fileBuffer);
insr.close();
return new String(fileBuffer);
}
}]]></source>
</section>
<p>
Much of this program is similar to what we've already seen in
our
other XML:DB programs. Really the only difference is the code
to add
the document.
</p>
<p>
Documents are added to the server
by first creating a new resource implementation from a
collection,
setting its content and then storing the resource to the
collection.
The type of resource that is created is an XMLResource this
can be
used to store XML as either text, a DOM Node or a SAX
ContentHandler.
</p>
<p>
If you had your content already in a DOM tree you could also
add
the document as a DOM.
</p>
<source><![CDATA[
XMLResource document = (XMLResource) col.createResource(null);
document.setContentAsDOM(doc); // doc is a DOM document
col.storeResource(document);
]]></source>
<p>
The only difference here is that you must have the document as
a DOM
Document already and then call
<code>setContentAsDOM()</code>. From there the
resource works the same as always.
</p>
<p>
One thing to note is that a resource must be stored in the same
collection from which it was originally created.
</p>
<section>
<title>Retrieving an XML Document from the Database</title>
<source><![CDATA[package org.apache.xindice.examples;
import org.xmldb.api.base.*;
import org.xmldb.api.modules.*;
import org.xmldb.api.*;
import java.io.*;
public class RetrieveDocument {
public static void main(String[] args) throws Exception {
Collection col = null;
try {
String driver = "org.apache.xindice.client.xmldb.DatabaseImpl";
Class c = Class.forName(driver);
Database database = (Database) c.newInstance();
DatabaseManager.registerDatabase(database);
col =
DatabaseManager.getCollection("xmldb:xindice:///db/addressbook");
XMLResource document = (XMLResource) col.getResource(args[0]);
if (document != null) {
System.out.println("Document " + args[0]);
System.out.println(document.getContent());
}
else {
System.out.println("Document not found");
}
}
catch (XMLDBException e) {
System.err.println("XML:DB Exception occured " + e.errorCode);
}
finally {
if (col != null) {
col.close();
}
}
}
}]]></source>
</section>
<section>
<title>Deleting an XML Document from the Database</title>
<source><![CDATA[package org.apache.xindice.examples;
import org.xmldb.api.base.*;
import org.xmldb.api.modules.*;
import org.xmldb.api.*;
import java.io.*;
public class DeleteDocument {
public static void main(String[] args) throws Exception {
Collection col = null;
try {
String driver = "org.apache.xindice.client.xmldb.DatabaseImpl";
Class c = Class.forName(driver);
Database database = (Database) c.newInstance();
DatabaseManager.registerDatabase(database);
col =
DatabaseManager.getCollection("xmldb:xindice:///db/addressbook");
Resource document = col.getResource(args[0]);
col.removeResource(document);
System.out.println("Document " + args[0] + " removed");
}
catch (XMLDBException e) {
System.err.println("XML:DB Exception occured " + e.errorCode);
}
finally {
if (col != null) {
col.close();
}
}
}
}]]></source>
</section>
</section>
</section>
<section>
<title>Using XPath to Query the Database</title>
<section>
<title>Introduction</title>
<p>
Xindice currently supports XPath as a query language. In many
applications XPath is only applied at the document level but in
Xindice XPath queries are executed at the collection level.
This
means that a query can be run against multiple documents and
the
result set will contain all matching nodes from all documents
in the collection.
The Xindice server also support the creation of indexes on
particular XPaths to speed up commonly used XPath queries.
</p>
</section>
<section>
<title>Using the XML:DB Java API</title>
<p>
The XML:DB API defines operations for searching single
documents as
well as collections of XML documents using XPath. These
operations
are exposed through the XPathQueryService. In order to query
single
documents you use the
<code>queryResource()</code> method and to query an entire
collection you use the
<code>query()</code> method.
</p>
<section>
<title>Querying with XPath</title>
<p>This example simply executes an XPath query against a
collection, retrieves the results as text and prints them
out.
</p>
<p>
You can find the source code for this example in
Xindice/java/examples/guide/src/org/apache/xindice/examples/Example1.java
</p>
<source><![CDATA[package org.apache.xindice.examples;
import org.xmldb.api.base.*;
import org.xmldb.api.modules.*;
import org.xmldb.api.*;
public class Example1 {
public static void main(String[] args) throws Exception {
Collection col = null;
try {
String driver = "org.apache.xindice.client.xmldb.DatabaseImpl";
Class c = Class.forName(driver);
Database database = (Database) c.newInstance();
DatabaseManager.registerDatabase(database);
col = DatabaseManager.getCollection("xmldb:xindice:///db/addressbook");
String xpath = "//person[fname='John']";
XPathQueryService service =
(XPathQueryService) col.getService("XPathQueryService", "1.0");
ResourceSet resultSet = service.query(xpath);
ResourceIterator results = resultSet.getIterator();
while (results.hasMoreResources()) {
Resource res = results.nextResource();
System.out.println((String) res.getContent());
}
}
catch (XMLDBException e) {
System.err.println("XML:DB Exception occured " + e.errorCode);
}
finally {
if (col != null) {
col.close();
}
}
}
}]]></source>
</section>
<p>TODO: cover namespace support</p>
</section>
</section>
<section>
<title>Using XUpdate to Modify the Database</title>
<section>
<title>Introduction</title>
<p>
XUpdate is a specification under development by the XML:DB
Initiative
to enable simpler updating of XML documents. It is useful
within the
context of an XML database as well as in standalone
implementations
for general XML applications. XUpdate gives you a declarative
method
to insert nodes, remove nodes, and change nodes within an XML
document. The syntax is specified in the
<link href="http://www.xmldb.org/xupdate/xupdate-wd.html">
XUpdate working draft</link> available on the XML:DB
Initiative website.
</p>
<p>
The XUpdate implementation in Xindice is based around the
Lexus XUpdate implementation that was developed by the
<link href="http://www.infozone-group.org/">Infozone
Group</link>.
</p>
<p>
The general model around XUpdate is to use an
<code>xupdate:modifications</code>
container to batch a series of XUpdate commands. All commands
will be performed in series against either a single XML
document or
an entire collection of XML documents as specified by the
developer.
</p>
<p>
Execution of XUpdate commands is performed in two phases.
First selecting a node set
within the document or collection and then applying a change
to the
selected nodes.
</p>
<section>
<title>Basic XUpdate Insert Command</title>
<source><![CDATA[<xupdate:modifications version="1.0"
xmlns:xupdate="http://www.xmldb.org/xupdate">
<xupdate:insert-after select="/addresses/address[1]" >
<xupdate:element name="address">
<xupdate:attribute name="id">2</xupdate:attribute>
<fullname>John Smith</fullname>
<born day='2' month='12' year='1974'/>
<country>Germany</country>
</xupdate:element>
</xupdate:insert-after>
</xupdate:modifications>]]></source>
</section>
</section>
<section>
<title>XUpdate Commands</title>
<ul>
<li>
<code>xupdate:insert-before</code> - Inserts a new node in
document order before the selected node.
</li>
<li>
<code>xupdate:insert-after</code> - Inserts a new node in
document order after the selected node.
</li>
<li>
<code>xupdate:update</code> - Replaces all child nodes of
the selected node with the specified nodes.
</li>
<li>
<code>xupdate:append</code> - Appends the specified node to
the content of the selected node.
</li>
<li>
<code>xupdate:remove</code> - Remove the selected node
</li>
<li>
<code>xupdate:rename</code> - Renames the selected node
</li>
<li>
<code>xupdate:variable</code> - Defines a variable
containing a node list that can be reused in later operations.
</li>
</ul>
</section>
<section>
<title>XUpdate Node Construction</title>
<ul>
<li>
<code>xupdate:element</code> - Creates a new element in the
document.
</li>
<li>
<code>xupdate:attribute</code> -
Creates a new attribute node
associated with an
<code>xupdate:element</code>.
</li>
<li>
<code>xupdate:text</code> - Creates a text content node in
the
document.
</li>
<li>
<code>xupdate:processing-instruction</code> - Creates a
processing instruction node in the document.
</li>
<li>
<code>xupdate:comment</code> - Creates a new comment node
in the
document.
</li>
</ul>
</section>
<section>
<title>Using the XML:DB API for XUpdate</title>
<p>
The XML:DB API provides an XUpdateQueryService to enable
executing
XUpdate commands against single documents or collections of
documents. To update a single document you use the
<code>updateResource()</code> method and to apply the updates
to an entire collection you use the
<code>update()</code>
method.
</p>
<p>
The next example program applies a set of XUpdate
modifications to
an entire collection of data. It first removes all elements
that
match the XPath
<code>/person/[EMAIL PROTECTED] = 'home']</code>
and then adds a new entry after all elements that match the
XPath
<code>/person/[EMAIL PROTECTED] = 'work']</code>
</p>
<section>
<title>Using XUpdate to modify the database</title>
<source><![CDATA[
import org.xmldb.api.base.*;
import org.xmldb.api.modules.*;
import org.xmldb.api.*;
/**
* Simple XML:DB API example to update the database.
*/
public class XUpdate {
public static void main(String[] args) throws Exception {
Collection col = null;
try {
String driver = "org.apache.xindice.client.xmldb.DatabaseImpl";
Class c = Class.forName(driver);
Database database = (Database) c.newInstance();
DatabaseManager.registerDatabase(database);
col =
DatabaseManager.getCollection("xmldb:xindice:///db/addressbook");
String xupdate = "<xu:modifications version=\"1.0\"" +
" xmlns:xu=\"http://www.xmldb.org/xupdate\">" +
" <xu:remove select=\"/person/[EMAIL PROTECTED] = 'home']\"/>" +
" <xu:update select=\"/person/[EMAIL PROTECTED] = 'work']\">" +
" 480-300-3003" +
" </xu:update>" +
"</xu:modifications>";
XUpdateQueryService service =
(XUpdateQueryService) col.getService("XUpdateQueryService", "1.0");
service.update(xupdate);
}
catch (XMLDBException e) {
System.err.println("XML:DB Exception occured " + e.errorCode + " " +
e.getMessage());
}
finally {
if (col != null) {
col.close();
}
}
}
}
]]></source>
</section>
</section>
</section>
<!--
<section>
<title>Using XMLObjects</title>
<section>
<title>Introduction</title>
<p>
XMLObjects provide a mechanism for extending the functionality of
the Xindice server. They are implemented in Java and are
configured at the collection level within the server. Building and
installing XMLObjects is quite simple but they still provide significant
power to extend the server with new functionality.
</p>
<p>
The uses for XMLObjects are many i.e. updating documents on the
server side, implementing a
custom query language or any other functionality where doing the
operation on the server side would be more efficient. The example
XMLObject included here will show you how you could implement a
single document query mechanism in the server even when Xindice by
default queries at the collection level.
</p>
<p>
Note: When writing XMLObjects you use the internal APIs for Xindice and
therefore have full access to the internals of the server. Because
of this you should exercise caution in the code that you write to
insure that it is robust and does not harm the operation of the
server.
</p>
</section>
<section>
<title>A Simple XMLObject</title>
<p>
XMLObjects are simply Java classes that extend SimpleXMLObject to
provide custom functionality within the server.
</p>
<p>
To get started let's take a look at a very simple Hello World XMLObject.
</p>
<section>
<title>A Hello World XMLObject</title>
<source><![CDATA[package org.apache.xindice.examples;
import org.apache.xindice.core.objects.*;
public class HelloWorldXMLObject extends SimpleXMLObject {
public String execute() {
return "Hello World";
}
}]]></source>
</section>
<p>
This simple XMLObject just defines one method
<code>execute()</code> that takes no parameters
and returns a String. The <code>execute()</code>
method name is special within the
context of XMLObjects because if no explicit method is specified
in the invocation request the XMLObject framework will call the
<code>execute()</code> method automatically.
</p>
<p>
To compile and install this XMLObject you need to make sure that you
have <code>xindice.jar</code> and the directory where the
XMLObject class file can be found in your
<code>CLASSPATH</code> environment variable. The
directory for the class file must also be available to the Xindice
server before you start it.
</p>
<p>
Once you have your classpath setup you can compile the XMLObject
like any other Java class and then install it in the
<code>/db/addressbook</code> collection.
</p>
<source><![CDATA[
xindice add_xmlobject -i
org.apache.xindice.examples.HelloWorldXMLObject -n Hello -c /db/addressbook
]]></source>
<p>
And then you can run it.
</p>
<source><![CDATA[
xindice invoke -c /db/addressbook -o Hello
]]></source>
<p>
One thing to note about this is that when you invoke the
XMLObject you need to use the name that you configured with the
<code>-n</code>
parameter to <code>add_xmlobject</code> not the
name of the class. In this case we named the object
<code>Hello</code> so that is
what we use to invoke it.
</p>
<p>
If all went well you should see something like this
</p>
<source><![CDATA[
Results =
Hello World
]]></source>
</section>
<section>
<title>Building the XPath Query XMLObject</title>
<p>
By default the Xindice XPath query functionality takes an XPath and
applies it against all documents stored in a collection to find a
set of matching nodes. Depending on our application this may not be
what we really want. The
<code>XPathQueryService</code> does support
doing this but it will be instructive to look at how we could roll
our own implementation to do the same thing.
</p>
<p>
To do this we first need to decide what information is required to
execute the query. First we need the XPath we want to execute and
second we need the key of the document within the collection. We
also need the collection itself but since XMLObjects are configured
at the collection level within the system this is taken care of
automatically.
</p>
<p>
Now that we know what data we need we can see that we're going to
need a method that takes two parameters, the xpath and the id. Once
we have these parameters we'll need to retrieve the document and
then use an XPath engine to select the nodes we want from the
document. Our solution might look something like this.
</p>
<section>
<title>Single Document XPath Query XMLObject</title>
<source><![CDATA[package org.apache.xindice.examples;
import org.apache.xindice.core.*;
import org.apache.xindice.core.objects.*;
import org.apache.xindice.xml.dom.*;
import org.w3c.dom.*;
import org.apache.xpath.*;
public class XPathQueryXMLObject extends SimpleXMLObject {
public static final String [] PARAMS_query = {"xpath", "id"};
public static final String [] DEFAULTS_query = {"/", ""};
public Document query(String xpath, String id) throws Exception {
Collection col = getCollection();
Document target = col.getDocument(id);
NodeList result = XPathAPI.selectNodeList(target, xpath);
// Turn the NodeList into a document.
Document doc = new DocumentImpl();
Element root = doc.createElement("result");
doc.appendChild(root);
int i = 0;
while ( (result != null) && (i < result.getLength()) ) {
root.appendChild(doc.importNode(result.item(i), true));
i++;
}
return doc;
}
}]]></source>
</section>
<p>
Delving into this in a little more detail we see several obvious
differences from our simple example.
</p>
<p>
First we're no longer using the default
<code>execute()</code> method and have defined
our own method named <code>query()</code>.
</p>
<p>
Next, we also have now added two contants to our class
<code>PARAMS_query</code> and
<code>DEFAULTS_query</code>. <code>PARAMS_query</code>
is used to define the names of the parameters that are required by
the query method. <code>DEFAULTS_query</code> defines the
default values that are provided for those parameters if the user
leaves out a parameter when invoking the XMLObject. These constants
are necessary to provide hints to the XMLObject engine on how to map
incoming parameters to the proper parameters on the method.
</p>
<p>
This XML Object is installed just like before except this time we're
going to configure it for the
<code>addressbook</code> collection.
</p>
<source><![CDATA[
xindice add_xmlobject -i
org.apache.xindice.examples.XPathQueryXMLObject -n XPath -c /db/addressbook
]]></source>
<p>
Before we can use it though we need some sample data. Again we're
using the familiar person XML. This should be
added to the database under the key address1.
</p>
<source><![CDATA[<?xml version="1.0"?>
<person>
<fname>John</fname>
<lname>Smith</lname>
<phone type="work">563-456-7890</phone>
<phone type="home">534-567-8901</phone>
<email type="home">[EMAIL PROTECTED]</email>
<email type="work">[EMAIL PROTECTED]</email>
<address type="home">34 S. Colon St.</address>
<address type="work">9967 W. Shrimp Ave.</address>
</person>
xindice add_document -c /db/addressbook -n address1 -f
address1.xml]]></source>
<p>
After adding this data we can now use our XMLObject
to retrieve nodes from just this document.
</p>
<source><![CDATA[xindice invoke -c /db/addressbook -o
XPath/query?xpath='/person/fname'&id=address1]]></source>
<p>
Note: on UNIX you will need to
escape the '&' with a '\' character to prevent its evaluation
by the shell. If all goes well the result will be.
</p>
<source><![CDATA[Results =
<!xml version="1.0"?>
<result><fname>John</fname></result>]]></source>
</section>
<section>
<title>Putting the XPath Query XMLObject to Work</title>
<p>
So far we've seen how to create a couple different XMLObjects, how
to install them in the server and how to invoke them from the
command line. While this alone is very useful, XMLObjects are really
much more useful when you use them from within another program.
</p>
<p>
Note: Since XMLObjects are a proprietary feature of Xindice we have to
use a
Xindice specific extension service for the XML:DB API to invoke them
from within our programs. This is important to note because
programs built to use XMLObjects will not be portable to other XML
databases.
</p>
<p>
In this example we'll use our XPathQueryXMLObject to build a very
simple program that queries for the street and then prints the the
value out.
</p>
<p>
For this example we'll use the same object configuration and sample
data as used in the previous section.
</p>
<section>
<title>Invoking the XPathQueryXMLObject via the XML:DB
API</title>
<source><![CDATA[package org.apache.xindice.examples;
import org.xmldb.api.base.*;
import org.xmldb.api.modules.*;
import org.xmldb.api.*;
// Import the Xindice specific XMLObjectService
import org.apache.xindice.client.xmldb.services.*;
public class XPathQueryInvoke {
public static void main(String[] args) throws Exception {
Collection col = null;
try {
String driver = "org.apache.xindice.client.xmldb.DatabaseImpl";
Class c = Class.forName(driver);
Database database = (Database) c.newInstance();
DatabaseManager.registerDatabase(database);
col =
DatabaseManager.getCollection("xmldb:xindice:///db/addressbook");
String xpath = "/person/fname";
String key = "address1";
XMLObjectService service =
(XMLObjectService) col.getService("XMLObjectService", "1.0");
Resource result =
service.invokeXMLObject("/db/addressbook/XPath/query?xpath=" +
xpath + "&id=" + key);
System.out.println((String) result.getContent());
}
catch (XMLDBException e) {
System.err.println("XML:DB Exception occured " + e.errorCode);
}
finally {
if (col != null) {
col.close();
}
}
}
}]]></source>
</section>
<p>
As you can see from the example calling an XMLObject from a program
is pretty similar to calling it from the command line. You simply
create the <code>XMLObjectService</code>
and then call <code>invokeXMLObject()</code>
handing it the URI just like you did on the command line.
</p>
<p>
The result that you receive is a Resource that will either contain a
string result or an XML result depending on the return type of the
XMLObject. If the XMLObject returns it's result as anything other
then a DOM Node or Document then the results are treated as a string
and should only be retrieved with
<code>result.getOutput()</code>. If the
XMLObject you are calling returns a DOM
<code>Node</code> or
<code>Document</code> then you can cast the
result to an XMLObject and use the
<code>getContentAsDOM</code> and
<code>getContentAsSAX</code> methods to retrieve
the content as well.
</p>
<p>
We've now seen how to contruct XMLObjects, install them in the
server and invoke them from the command line and our custom
programs. Hopefully you see the value in these powerful server side
extensions for Xindice and can use them when necessary to improve your
applications.
</p>
</section>
</section>
-->
<section>
<title>Address Book Example Application</title>
<section>
<title/>
<p>
The address book example is a simple servlet based application
constructued using Xindice. For more information on this
example look
in the
<code>Xindice/java/examples/addressbook</code>
directory.
</p>
<p>
TODO: Add more detail about building servlet applications.
</p>
</section>
</section>
<section>
<title>Experimental Features</title>
<p>
There are a couple features in Xindice that are definitely
experimental. These features can be interesing to explore to see
some
things that could be useful in future versions of Xindice but
they should
not be considered complete or stable.
</p>
<!--
<section>
<title>Auto Linking</title>
<p>
Xindice provides a facility for automating relational links between
managed documents called AutoLinking. This allows you to break out
duplicate data into shared documents or include a dynamic element
such as the output of a query or XMLObject invocation into an XML
file stored in the repository.
</p>
<p>
AutoLinking is specified by adding special attributes to the XML
tag defining the link. This works in a similar manner to Xlink from
the W3C. The attributes must use the
xmlns:db="http://xml.apache.org/xindice/XMLObject" namespace. There are two
attributes to be concerned with href and type.
</p>
<p>
db:href attribute:
Defines the URI for the resource that this AutoLink should retrieve.
</p>
<p>
db:type attribute:
Specifies how this link should be processed. The following
mechanisms are available.
</p>
<ol>
<li>
replace - Replaces the linking element with the content of
the href URI
</li>
<li>
content - Replaces all child content of the linking element
with the content of the href URI. The linking element is not
replaced.
</li>
<li>
append - Appends the content of the href URI to the content
of the linking element.
</li>
<li>
insert - Inserts the content of the href URI as the first
child of the linking element.
</li>
</ol>
<section>
<title>Auto-Linking Using Replace</title>
<p>
This example will replace the some-element element with the
contents of the URI xindice:///db/ocs/test/some-document.
</p>
<source><![CDATA[<document>
<some-element xmlns:db="http://xml.apache.org/xindice/XMLObject"
db:href="xindice:///db/ocs/test/some-document"
db:type="replace"/>
</document>]]></source>
<p>After expanding the link it will look something like
this.</p>
<source><![CDATA[<document>
<some-document>
...
</some-document>
</document>]]></source>
</section>
<section>
<title>Auto-Linking Using Insert</title>
<p>
The following link will insert the content of the document found
at xindice:///db/ocs/test/some-document as the first child of
the element some-element.
</p>
<source><![CDATA[<document>
<some-element xmlns:db="http://xml.apache.org/xindice/XMLObject"
db:href="xindice:///db/ocs/test/some-document"
db:type="insert"/>
</document>]]></source>
<p>
After linking the document will look like.
</p>
<source><![CDATA[<document>
<some-element xmlns:db="http://xml.apache.org/xindice/XMLObject"
db:href="xindice:///db/ocs/test/some-document"
db:type="insert">
<some-document>
...
</some-document>
</some-element>
</document>]]></source>
</section>
</section>
-->
</section>
</body>
</document>
1.1
xml-xindice/src/documentation/content/xdocs/dev/guide-user.xml
Index: guide-user.xml
===================================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN"
"document-v11.dtd">
<!--
- Version: $Revision: 1.1 $ $Date: 2002/11/17 08:16:03 $
- Author: Kimbro Staken ([EMAIL PROTECTED])
-->
<document>
<header>
<title>User Guide</title>
<authors>
<person id="ks" name="Kimbro Staken" email=""/>
</authors>
<notice/>
<abstract/>
</header>
<body>
<warning>This documentation is a work in progress and is only
applicable to the CVS version of Xindice. There is absolutely no guarantee that
this information is accurate. You have been warned.
</warning>
<section>
<title>Introduction to Xindice</title>
<section>
<title>What Is Xindice</title>
<p>
The Xindice Core server is a database server designed from the
ground up to store XML data. The
Xindice server is what is termed by
the
<link href="http://www.xmldb.org">XML:DB Initiative</link>
as a Native XML Database. You could also refer to it as a
seamless XML database which might be an easier to understand
description.
</p>
<p>
What this means is that to the largest extent possible you work
with XML tools and technologies when working with the data in
the
server. All data that goes into and out of the server is XML.
The
query language used is XPath and the programming APIs support
DOM
and SAX. All things that should be familiar to a developer used
to using XML in their applications. When working with XML data
and
Xindice there is no mapping between different data models. You
simply
design your data as XML and store it as XML.
</p>
<p>
What this gives you can be summed up in one word, flexibility.
XML
provides an extremely flexible mechanism for modeling
application
data and in many cases will allow you to model constructs that
are
difficult or impossible to model in more traditional systems.
This
model is a semi-structured model and for some applications it
is
an essential component. By
using a native XML database such as Xindice to store this data
you can
focus on building your applications and not worry about how the
complex XML construct maps to the underlying data store or
trying
force a flexible data model into a rigid set of schema
constraints.
</p>
<p>
Ultimately though, Xindice is a tool. It will be right for
some jobs
and completely wrong for others. The job it is best at is
simply
storing XML data. In fact, that's all it does. If you have
lots of
XML data then Xindice may just be the right tool. However, if
your
data isn't XML or if you have the need for precise control over
the structure of the data you might be better off using another
database solution.
</p>
</section>
<section>
<title>Current Status</title>
<p>
Native XML database technology is a very new area and Xindice
is very
much a project still in development.
The server currently supports storing well formed XML
documents.
This means it does not have any schema that constrains what
can be placed into a document collection. This makes Xindice a
semi-structured database and provides tremendous
flexiblity in how you store your data, but, also means you
give up
some common database functionality such as data
types.
In its current
state Xindice is already a powerful tool for managing XML data.
However, there is still much that needs to be done. Feedback
and
contributions are actively encouraged.
</p>
<p>
This document attempts to
describe those features that are working and can be used today.
You should review the README file that is part of the Xindice
distribution for the most current status on the project.
</p>
<p>
NOTE: Both the Xindice server and this document are works in
progress. Any comments are welcome and encouraged.
</p>
</section>
<section>
<title>Feature Summary</title>
<p>
Document Collections: Documents are stored in collections that
can
be queried as a whole. You can create collections that contain
just
documents of the same type or you can create a collection to
store
all your documents together. The database doesn't care.
</p>
<p>
XPath Query Engine: To query the Document Collections you use
<link href="http://www.w3.org/TR/xpath">XPath</link> as defined
by the W3C. This provides a reasonably flexible mechanism for
querying documents by navigating and restricting the result
tree
that is returned.
</p>
<p>
XML Indexing: In order to improve the performance of queries
over
large numbers of documents you can define indexes on element
and
attribute values. This can dramatically speed up query response
time.
</p>
<p>
XML:DB XUpdate Implementation: When you store XML in the
database
you may want to be able to change that data without retrieving
the
entire document. XUpdate is the mechanism to use when you want
to do
server side updates of the data. It is an XML based language
for
specifying XML modifications and allows those modifications to
be
applied to entire document collections as well as single
documents.
</p>
<p>
Java XML:DB API Implementation: For Java programmers Xindice
provides
an implementation of the XML:DB API. This API is intended to
bring
portability to XML database applications just as JDBC has done
for
relational databases. Most applications developed for Xindice
will use
the XML:DB API.
</p>
<p>
XMLObjects: XMLObject provide a server extension mechanism for
adding extra functionality to the server. They can be used to
execute complex operations within the database engine to cut
down on
network bandwidth or to add functionality that doesn't
currently
exist in the server.
</p>
<p>
Command Line Management Tools: To aid the administrator Xindice
provides a full suite of command line driven management tools.
Just
about everything you can do through the XML:DB API can also be
done
from the command line.
</p>
<p>
CORBA Network API: For developers who are interested in
working in
languages other then Java, Xindice provides a CORBA API that
can be
used to build applications. All functionality available
through the
XML:DB API is also available through the CORBA API. In fact the
XML:DB API is built on top of the CORBA API. Most Java
developers
though, will never even need to know that the CORBA API exists.
</p>
<p>
Modular Architecture: The Xindice server is constructed in a
very
modular manner. This makes it easy to add and remove
components to
tailor the server to a particular environment or to embed it
into
another application.
</p>
</section>
<section>
<title>Database Structure</title>
<p>
The Xindice server is designed to store collections of XML
documents.
Collections can be arranged in a hierarchy similar to that of a
typical UNIX or Windows file system.
</p>
<p>
In Xindice the data store is rooted in a database instance
that can
also be used as a document collection. This
database instance can then contain any number of child
collections.
In a default install of Xindice the database instance is called
'db' and all collection paths will begin with /db. It is
possible to
rename the database instance if desired though it is not
necessary
to do so.
</p>
<p>
Collections are referenced in a similar manner to how you
would work with a hierarchical file system.
</p>
<section>
<title>Collection Path Example</title>
<p>
If you had a collection
created under 'db' called my-collection and a collection
under
that called my-child-collection the path used when
accessing the
my-child-collection collection would be
</p>
<source><![CDATA[
/db/my-collection/my-child-collection
]]></source>
</section>
<p>
Within collections there are several types of objects that can
be
stored. You can store XML documents, XMLObjects and other
collections. Each of these objects can also be referenced via a
path.</p>
<section>
<title>Collection Path Referencing a Document</title>
<p>
Extending the previous example by adding a document to
my-child-collection named my-document it to could be
referenced via a path.
</p>
<source><![CDATA[
/db/my-collection/my-child-collection/my-document
]]></source>
</section>
<p>
There is one catch to this however. Since you can have more
then one
object in a collection with the same name
there is an order of precedence that is applied when
evaluating a
path. The order of precendence is collection followed by
XMLObject
and then document. What this means is that if you have a
document
and a collection with the same name you will not be able to
retrieve
the document.
</p>
<p>
You can also access collections on remote machines by
specifying the host
and port of the server.
</p>
<section>
<title>Collection Path Referencing a remote Document</title>
<p>
If the previous example was on a remote machine the path
would look
something like this.
</p>
<source><![CDATA[
myhost.domain.com:4080/db/my-collection/my-child-collection/my-document
]]></source>
<p>
This can also take the form of a Xindice URI.
</p>
<source><![CDATA[
xindice://myhost.domain.com:4080/db/my-collection/my-child-collection/my-document
]]></source>
</section>
</section>
<section>
<title>Introducing the Command Line Tools</title>
<p>
The Xindice server includes a command line program named
<code>xindice</code> that allows you to manage the
data stored in the server.
A complete list of available commands and more
detail about each command can be found in the
<link href="guide-tools.html">Command Line Tools Reference
Guide</link>.
</p>
<p>
The
<code>xindice</code> tool is located in the
Xindice-Core/bin directory and it is
probably a good idea to add this directory to your PATH
environment
variable. All examples in this manual will assume that the
Xindice-Core/bin directory is on the operating system path.
</p>
</section>
</section>
<section>
<title>Managing Documents</title>
<section>
<title>Introduction</title>
<p>
In many ways the Xindice database can be viewed as a simple
file
store. This is of course a highly simplified view of things but
is a useful place to get started in learning the functionality
of
the server.
</p>
<p>
The Xindice server provides facilities to store, retrieve and
delete well formed XML documents.
</p>
</section>
<section>
<title>Adding Documents</title>
<p/>
<section>
<title>Adding a Document With a Given Key</title>
<p>
The document fx102.xml will be added to the collection
/db/data/products and will be stored under the key fx102.
</p>
<source><![CDATA[
xindice add_document -c /db/data/products -f fx102.xml -n fx102
]]></source>
</section>
<section>
<title>Adding a Document Without a Key</title>
<p>
The document fx102.xml will be added to the collection
/db/data/products. No key is provided so one will be
generated
automatically by the server. The generated key will look
similar
to this 0625df6b0001a5d4000bc49d0060b6f5
</p>
<source><![CDATA[
xindice add_document -c /db/data/products -f fx102.xml
]]></source>
</section>
</section>
<section>
<title>Retrieving Documents</title>
<p>
Documents can be retrieved from the database using the ID that
they were inserted under.
</p>
<section>
<title>Retrieving a Document Using an ID</title>
<p>
The document identified by the key fx102 will be retrieved
from
the /db/data/products collection and stored in the file
fx102.xml
</p>
<source><![CDATA[
xindice retrieve_document -c /db/data/products -n fx102 -f fx102.xml
]]></source>
</section>
</section>
<section>
<title>Deleting Documents</title>
<p/>
<section>
<title>Deleting a document using an ID</title>
<p>
The document identified by the key fx102 will be removed
from the
collection /db/data/products.
</p>
<source><![CDATA[
xindice delete_document -c /db/data/products -n fx102
]]></source>
</section>
</section>
</section>
<section>
<title>Querying the Database</title>
<p>
Xindice currently supports XPath as a query language. In many
applications XPath is only applied at the document level but in
Xindice XPath queries can be executed at either the document level
or the collection level. This
means that a query can be run against multiple documents and the
result set will contain all matching nodes from all documents
in the collection.
The Xindice server also supports the creation of indexes on
XML documents to speed up commonly used XPath queries. Please
refer
to the
<link href="guide-administrator.html">Administrators
Guide</link> for more detail about configuring indexes.
</p>
<p>
You can execute XPath queries against the database using the
command
line tools and the result of the query will be displayed.
</p>
<section>
<title>
Executing an XPath query against a collection of XML documents
</title>
<p>
Here we assume we have a collection /db/data/products that
contains
documents that are similar to the following.
</p>
<source><![CDATA[<?xml version="1.0"?>
<product product_id="120320">
<description>Glazed Ham</description>
</product>]]></source>
<p>
The XPath /[EMAIL PROTECTED]"120320"] will be executed against
the collection /db/data/products and all matching product
entries
will be returned.
</p>
<source><![CDATA[
xindice xpath_query -c /db/data/products -q /[EMAIL PROTECTED]"120320"]
]]></source>
<p>
The result of the query is an XPath node-set that contains one
node for each result. In this particular example there is only
one result and the node that matches is the root element so you
get back basically the whole document.
</p>
<p>
To make it easy to link the result node back to the originating
document, Xindice adds a few attributes to the result. These
attributes
are added in the NodeSource namespace that has the URI
http://xml.apache.org/xindice/NodeSource. The
<code>col</code> attribute specifies the
collection where the document can be found and the
<code>key</code> attribute
provides the key of the original document. Using this
information it
is possible to retrieve the original document that this node
was
selected from for further processing.
</p>
<source><![CDATA[<product product_id="120320"
xmlns:src="http://xml.apache.org/xindice/NodeSource"
src:col="/db/data/products" src:key="120320">
<description>Glazed Ham</description>
</product>]]></source>
<p>
If more then one result is found the results look something
like
this. This could be the result of the query /product
</p>
<source><![CDATA[
<product product_id="120320"
xmlns:src="http://xml.apache.org/xindice/NodeSource"
src:col="/db/data/products" src:key="120320">
<description>Glazed Ham</description>
</product>
<product product_id="120321"
xmlns:src="http://xml.apache.org/xindice/NodeSource"
src:col="/db/data/products" src:key="120321">
<description>Boiled Ham</description>
</product>
<product product_id="120322"
xmlns:src="http://xml.apache.org/xindice/NodeSource"
src:col="/db/data/products" src:key="120322">
<description>Honey Ham</description>
</product>]]></source>
</section>
<p>
While it is certainly useful to be able to query from the command
line it is probably more useful to be able to use the results of
a
query in an application. For more information on building
applications for Xindice, please refer to the
<link href="guide-user.html">Developers Guide</link>.
</p>
</section>
<!--
<section>
<title>XMLDB Error codes</title>
<p>
public static final int UNKNOWN_ERROR = 0;
public static final int VENDOR_ERROR = 1;
public static final int NOT_IMPLEMENTED = 2;
public static final int WRONG_CONTENT_TYPE = 3;
public static final int PERMISSION_DENIED = 4;
public static final int INVALID_URI = 5;
public static final int NO_SUCH_SERVICE = 100;
public static final int NO_SUCH_COLLECTION = 200;
public static final int INVALID_COLLECTION = 201;
public static final int COLLECTION_CLOSED = 202;
public static final int NO_SUCH_RESOURCE = 300;
public static final int INVALID_RESOURCE = 301;
public static final int UNKNOWN_RESOURCE_TYPE = 302;
public static final int NO_SUCH_DATABASE = 400;
public static final int INVALID_DATABASE = 401;
</p>
</section>
-->
</body>
</document>
1.1 xml-xindice/src/documentation/content/xdocs/dev/index.xml
Index: index.xml
===================================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN"
"document-v11.dtd">
<!--
- Version: $Revision: 1.1 $ $Date: 2002/11/17 08:16:03 $
- Author: Vladimir R. Bossicard ([EMAIL PROTECTED])
-->
<document>
<header>
<title>Dev Zone</title>
<authors>
<person name="Vladimir R. Bossicard" email="[EMAIL PROTECTED]"/>
</authors>
</header>
<body>
<section>
<title>Introduction</title>
<p>The Xindice team is currently preparing a major release and try to
catch up with the numerous points still open. These pages describe
what has been done but also the amount of work that still needs to
be done. If you have interest in the project, your help is
welcome!</p>
</section>
<section>
<title>Development Status</title>
<p>The project really needs your help in the following areas:</p>
<ul>
<li>
<strong>bug reports</strong>: according to the number of bugs
found in the bug database, Xindice has almost no bugs at all.
Well the experience shows that the reality is different. We
can't fix bugs if we don't know where they are! So if you find
a bug, please report it with information.
</li>
<li>
<strong>new documentation</strong>: everyone who uses Xindice
must contribute to the documentation. Period. Simply read the
guides, correct the mistakes and send a patch would already
help tremendoulsy.
</li>
<li>
<strong>accurate how-tos</strong>: installing Xindice is for a
lot of users a real nightmare. And this shouldn't be the case.
The goal is to provide simple and detailed
<link href="../howto/index.html">how-tos</link>. If you are
installing Xindice, please follow the how-to and review its
accuracy. If there is none, you'll have to write and and send
it to use.
</li>
<li>
<strong>local patches</strong>: if you have locally modified
Xindice to fix a bug, please provide a patch! Or at least
discuss the modifications on the
<link href="../mail.html">mailing list</link>.
</li>
</ul>
</section>
</body>
</document>
1.1 xml-xindice/src/documentation/content/xdocs/dev/news.xml
Index: news.xml
===================================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN"
"document-v11.dtd">
<!--
- Version: $Revision: 1.1 $ $Date: 2002/11/17 08:16:03 $
- Author: Vladimir R. Bossicard ([EMAIL PROTECTED])
-->
<document>
<header>
<title>Dev News</title>
</header>
<body>
<ul>
<li>
<strong>17 November 2002</strong>: the new website is published.
Many thanks to Kevin (guides), Nicola (logo) and Jeff (Forrest
hotline). And me (Vladimir) for the overall migration :-)
</li>
</ul>
</body>
</document>