XStreamDB User Guide

Introduction

XStreamDB is a native XML database for storing, retrieving and manipulating XML documents.

This user guide describes the four main components of the XStreamDB package:

This guide also provides introductions to:

This guide does not cover the XdbWeb application - see the ReadMe for a link. XdbWeb is a set of utility servlets that allow you to work with XStreamDB resources using http.

XStreamDB Server

Overview

The XStreamDB server is the heart of the XStreamDB system.

The server is started as a process under any operating system that supports Java 1.4.

Client software connects to the server using the XDB client libraries, as defined in the XDB API. The client libraries connect to a server using the host address and port that the server is listening on, as provided or configured by the client software. If a client uses a host name instead of an IP number, then a DNS must be available to resolve name to IP number. The default port for the server is 1223. However, it can be changed manually by editing the XDBServer.prop file located in the Server/conf directory.

More information on Server properties is contained in the "Other" section of the Reference Manual . Detailed installation instructions can be found in the InstallDeploy manual, including a discussion on how to install the server as a Windows service.

Starting and Stopping the Server

The easiest way to start and stop the Server is by using the shortcuts "XStreamDB Server Start" and "XStreamDB Server Stop". In Windows, these shortcuts are found on the Desktop or in the Start menu. The server can also be started or stopped using the runServer command file located in the folder {XStreamDB Home}/Server/bin.

Use the "XStreamDB Server Stop" shortcut or runServer stop on the command line to stop the server. This avoids database recovery when the server is restarted, and ensures that no users have active transactions before shutting down the server. Killing the process from the operating system is also possible. However, database recovery will be invoked the first time a database is accessed after a subsequent start of the XStreamDB server process.

Database recovery can be quite time intensive when indexes exist and have to be rebuilt. Also, any transactions that were in progress when the server was stopped or terminated will be automatically rolled back on startup.

XStreamDB Explorer

Introduction

The XStreamDB Explorer is a GUI application for configuring and managing an XStreamDB server, the data it contains (including ancillary objects like schemas, triggers, indexes and modules), the users who have access to it, and setting and enforcing permissions and security. Additionally, the Explorer provides an interface for writing and executing XQuery statements on a server.

Use the Explorer for the following tasks:

Starting the Explorer

Start the Explorer by clicking the "XStreamDB Explorer" shortcut. In Windows, this shortcut icon is on the Windows Desktop or Start menu. Alternatively, run explorer.bat in the folder {XStreamDBHome}/Client/Explorer.

Configuring the Server

From the Configuration tab you can create and manage XStreamDB objects, manage security, and perform backup and restore:

Databases

About Databases

Databases can be created, modified and deleted from the Configuration tab. A list of databases can be seen by clicking on the DATABASES icon in the left pane of the Configuration tab. If you right click on one of the database names, a context menu will list the available actions for that database. Database actions can include:

  • New Root - Creating a new Root associated with the selected database
  • Delete - Permanently removing the selected database
  • Permissions . Viewing and modifying security settings for users and groups
  • Backup - Scheduling a backup of this database
  • Properties - Viewing details about the selected database
Creating a Database

To create a new database, right click on the DATABASES icon in the left pane of the Configuration tab to display the context menu, then select New Database . A New Database dialog box opens. Enter the name of the new database, then click OK to create the database. When complete, a new database icon with the new database name will be displayed under the DATABASES icon. Depending upon your permission settings, you may not be allowed to perform this operation.

Deleting a Database

To delete a database, right click on its Database icon in the left pane of the Configuration tab to display the context menu, then select Delete . A confirmation dialog box opens. Click OK to proceed or Cancel to abort. The selected database and all objects associated with it will be deleted. Depending upon your permission settings, you may not be allowed to perform this operation.

Refreshing the Databases

Refresh updates your local view of the database configuration with the most up to date information from the XStreamDB server. To refresh your view, right click on the DATABASES icon in the left pane of the Configuration tab to display the context menu, then select Refresh .

Note : A local Explorer configuration view can become out of date when other users modify the configuration, or when you execute statements (in the Statement tab) like CREATE ROOT to modify the configuration directly. Also, certain parts of the Resource subsystem may also add system roots that are not visible until you do a refresh of DATABASES .

Roots

About Roots

A Root is a named collection of XML documents stored in the database. Roots are typically used to organize groups of related documents. A single database may have as many different Roots as you require in order to manage your documents.

Roots can have two other objects associated with them: Indexes and Schemas. Indexes are used automatically where they exist to speed up data retrieval during queries. Schemas, when associated with a root, restrict the use of that root to documents which conform to the specified schema definition. This provides a first level integrity check on documents that are being inserted or updated.

Right click on a root in the left pane of the Configuration tab to display its context menu.

Choose from the following list, actions you can perform on the selected root:

  • Add Documents - Inserts an XML document from the file system into the selected root
  • Delete Root - Permanently removes the selected root
  • Schema - Associates a schema with a root (the selected schema must have been previously added to the XStreamDB Schema Repository)
  • User Permissions - View and modify security settings for individual users
  • Group Permissions - View and modify security settings for groups
  • Backup - Backs up all objects associated with the selected root (backups can be scheduled to be performed daily or weekly)
  • Properties - View details about the selected root

Indexes and triggers for a root are indicated in the two sub trees below the root name.

Right click on one of these subtree icons to display a context menu with the following actions:

  • New Index - Defines and creates either a Value Index or a Full Text Index for the selected root
  • New Trigger - Defines and creates a trigger for the selected root
Creating a Root

To create a new root in a database, right click on the Database icon in the left pane of the Configuration tab to display the context menu, then select New Root . The new root dialog box will be displayed. Enter the name of the new root, then click OK to physically create the root. When complete, a new root icon with the new root name will be displayed under the selected database. Depending upon your permission settings, you may not be allowed to perform this operation.

Deleting a Root

To delete a root, right click on its Root icon in the left pane of the Configuration tab to display the context menu, then click Delete Root . A confirmation dialog box opens. Click Yes to delete the selected root and all objects associated with it, or No to abort. Depending upon your permission settings, you may not be allowed to perform this operation.

Associating a Schema with a Root

To associate a schema with a root, right click on the Root icon in the left pane of the Configuration tab to display the context menu, then select Schema . The root properties dialog opens at the Schema tab. The Schema tab displays the full schema path of the currently attached schema (if any) for the selected root, and gives you the choice of either attaching or removing a schema.

If you click Attach Schema , a further dialog (see below) appears, listing all schemas in the XStreamDB Schema Repository in the left pane. Clicking on a schema will list all root elements in that schema in the right pane. Selecting one of the root elements will display the full schema path in the text field at the bottom of the dialog. Click OK to attach the schema to the selected root.

Note: All documents in the root must conform to the selected schema definition in order to successfully complete this operation.

Clicking on Remove Schema causes the schema to no longer be associated with the selected root.

Note: Removing a schema from a root does not delete the schema from the XStreamDB Schema Repository. Refer to Configuring_Schemas for instructions on adding and removing schemas.

Inserting Documents

If you right click on the desired Root icon in the Configuration tab, the popup menu will have an Add Documents entry. Clicking on Add Documents displays the Open File dialog window, which is used to select the documents, or XML files, you would like to insert into the selected Root. You may select a single document, multiple documents or all documents within a folder. Also, with a folder selection, you have the option to recurse into all subfolders by selecting the checkbox at the bottom of the file dialog.

Note: If you have a resource defined for this root, this dialog does not insert the resource also. This is covered in the section on Working with Resources below.

Indexes

About Indexes

Indexes are created on roots to improve the performance of the XStreamDB XQuery Engine for queries on documents in those roots. They can be created and deleted, but indexes are never accessed by a client directly. Indexes are used automatically by the XQuery Engine wherever possible. Note: Depending upon your permission settings, you may not be allowed to create and delete indexes.

Creating an Index

XStreamDB supports two types of indexes: value and full text. A value index is a simple index based on a particular element or attribute value. The full text index is much broader in scope, as it indexes all element and attribute text. Both types apply to all the documents held under a single root upon which the index is defined.

To create an index on a Root, right click on the Index icon under the selected Root in the left pane of the Configuration tab. Select New Index from the context menu. A sub-menu is displayed with the choice of either Value or Full Text .

Creating a Value Index

To create a value index, select Value to open the new value index dialog.

If a schema has been associated with the selected root, the schema tree for that root will be displayed in the dialog. Clicking on any leaf node within the schema tree will create the XPath expression and display it in the XPath textfield.

Enter the name for the new index and, if no schema tree is displayed, the XPath expression specifying the document node to be indexed. Note: The XPath must end with /data() for it to be considered a valid path for indexing purposes.

Indicate that this index is unique by selecting the Unique Index checkbox.

Click OK to index all the documents held by the associated root according to the Indexing XPath provided.

Creating a Full Text Index

To create a full text index, select Full Text from the sub-menu (shown above). This will immediately create the full text index, with the name BdsFtIdx, on the selected root. Note: A root can only have a single full text index.

Deleting an Index

To delete an index, right click on the specified Index icon in the left pane of the Configuration tab to display the context menu, then select Delete Index . A confirmation dialog box opens. Click OK to delete the index or Cancel to abort.

Triggers

About Triggers

A trigger is an XQuery statement that is executed either BEFORE or AFTER a document is INSERTED, UPDATED or DELETED in a Root.

Triggers are often used to maintain referential integrity in the database, or for audit logging. For example, you could create a trigger that automatically validates the contents of a document before it is inserted into a root. A trigger may also execute stored functions contained in a module.

Creating a Trigger

To create a trigger on a Root, right click on the Trigger icon under the selected Root in the left pane of the Configuration tab to display the context menu, then select New Trigger . The new Trigger dialog opens.

Enter the Trigger Name and the XQuery Statement to be executed when the specified action occurs. The new trigger dialog automatically includes an example XQuery statement for the trigger, which you can overright. Also note that the trigger's XQuery statement must use the LET and RETURN syntax as shown in the example.

Enter the Action, Timing, Priority and Prologue.

  • An Action is the type of document transaction on the Root that executes the trigger. It can be one of INSERT, UPDATE or DELETE.
  • Timing determines whether the trigger is executed BEFORE or AFTER the transaction is applied to the Root.
  • If there is more than one trigger for a Root, they are executed in the order specified by the Priority . Triggers with lower priority number are executed before triggers with higher numbers (e.g. a trigger with priority 1 will execute before a trigger with priority 2), and no execution order is enforced between triggers with the same priority.
  • The Prologue is an optional namespace directive. The example below defines the namespace "http://bluestream.com/mynms":
    namespace pre = "http://bluestream.com/myns"

Click OK to create the trigger on the root. Depending upon your permission settings, you may not be allowed to perform this operation.

Deleting a Trigger

To delete a trigger, right click on its Trigger icon in the left pane of the Configuration tab to display the context menu, then select Delete Trigger . A confirmation dialog box opens. Click OK to delete the trigger or Cancel to abort. Depending upon your permission settings, you may not be allowed to perform this operation.

Modules

About Modules

A module is either a library module or a main module. A library module is a collection of XQuery functions collected together into a module. A main module is a single XQuery expression. You can create, modify and delete libraries of functions. Depending upon your permission settings, you may not be allowed to perform any of these operations.

Creating a Module

To create a module, right click on the MODULES icon under the Server icon in the left pane of the Configuration tab to display the context menu, then select New Module . The new Module dialog opens.

Enter the module definition in the large text box. A module definition consists of text that names the module, defines the namespace, and defines all the functions contained in the module. An example is preloaded in the dialog box as follows:

Example: 
Create Module "MyModule" 
namespace pre = "http://bluestream.com/myns" 
DEFINE FUNCTION square(element $val) returns xsd:decimal 
{
   $val/data() * $val/data()
}

In this example, the new module name is "MyModule", its namespace is "http://bluestream.com/myns", and one function called "square" is defined. Any number of functions can be contained within a single module.

Click OK to create the new module, or Cancel to abort. When a new module is created, the functions it contains are loaded into cache, and prepared for immediate use.

To view the list of modules, select the MODULES icon in the left pane of the Configuration tab. A table list of the modules is displayed in the right pane.

Deleting a Module

To delete a module, first click on the MODULES icon in the left pane of the Configuration tab to display the list of modules. Then, right click on the module name you wish to delete from the list of modules in the right pane, displaying the context menu, and select Delete Module . A confirmation dialog box opens. Click Yes to delete the module or No to cancel.

Backup and Restore

XStreamDB includes a backup and restore feature. The backup format is a zip file containing fully expanded XML and binary files. This feature can be accessed by executing queries using the XStreamDB XQuery Engine or through the Explorer. It is recommended that the scheduled backup feature be used from the Explorer for anyone serious about regular backup. The Explorer can also be used to perform partial or full server backups and partial or full server restores. When you do a full server backup and restore, it includes the schemas, users, permission settings, databases, roots and all resource objects. Note : You must be the administrator to perform any backup or restore operation.

Backup and restore can be performed on the following objects:

  • Server
  • Database
  • Root
Backup

To perform a backup, right click on either the server name (for a full server backup), a database icon (for a database backup) or a root icon (for a root backup) and select Backup . A further popup menu will be displayed with a choice of either Backup Now or ScheduleBackup . The screenshot below shows the selection of Backup by right clicking on the server icon called "MyServer".

Immediate Backup

To perform an immediate backup, select Backup Now . A prompt will be displayed where the name of the backup file can be entered. You can alternatively choose to use the default filename, which consists of a filename based on the date and time the backup operation was performed. Note: If the backup file specifies a file that already exists, it is overwritten.

Scheduled Backup

To schedule a backup, select Schedule Backup . A dialog box will be displayed allowing you to schedule a new backup, and edit or delete an existing backup. The screenshot below shows this dialog box with two existing scheduled backups.

To schedule a new backup, click the Add button and a second dialog box will be displayed. From this dialog box, you have a choice between daily or weekly intervals. Make all necessary selections and click OK .

Restore

Restoring from a previous backup is done by right clicking on the Server icon within the configuration tab. A dialog (below left) appears that requires a:

  • Backup Archive to Restore . This is the name of a zip file that was previously created using Backup. Clicking on the elipsis button next to the textfield will display a dialog (below right) listing all backup archives to choose from.
    Server Restore Dialog
    Backup Archive to Restore
  • Archive Source List . This is a single path to a backed up object as selected from the Archive Source List tree (below right). If a full server restore is required, the Archive Source List and the Destination path will show as "/".
    Server Restore Dialog
    Archive Source List
  • Destination . This is the destination path. By default it refers to the same name as the Archive Source List, however you may change this value to a new path as necessary. Note: you must change this value if the path of the object already exists on your server since restore does not overwrite existing objects.

Configuring Schemas

A schema must be created externally before it can be added to the Schemas Repository in XStreamDB. Once the schema has been added to the repository, it can be viewed, deleted or attached to a root. Attaching a schema to a root enforces that all XML documents within that root comply to the grammatical rules of the schema. Note: Depending upon your permission settings, you may not be allowed to perform any operations associated with schemas. In addition, you may not be allowed to view any schemas

If you right click on the SCHEMAS icon, a popup context menu lists the available actions as follows:

  • Add Schema - Add an XML schema to the repository from the file system
  • Add Folder - Add a folder to organize schemas in hierarchical groups (required in complex schemas like OAGIS)
  • Delete All Schemas - Delete all schemas from the repository
  • Refresh - Refresh the display of schemas in the repository

Once a schema has been added to the repository, you can delete it by right clicking on the Schema icon and selecting Delete Schema from the popup context menu. To view a schema's global elements and their structure, you can simply click on the Schema icon.

Add a Schema

To add a schema to the schemas repository, right click on the Schema icon in the left pane of the Configuration tab, then select Add Schema from the context menu. Select the XML schema or DTD from the file open dialog box, and click OK .

It is recommended that if you are adding a group of related schemas, you create a folder (see below) to contain those schemas. Any schemas imported or included by the schema either directly or indirectly will be added to the schema respository automatically.

Schema Folders

To add a schema folder, right click on the SCHEMAS icon or a schemas folder in the left pane of the Configuration tab, displaying the context menu. Select Add Folder to display the add folder dialog. Enter a name for the new folder and click OK to create the new folder under the selected node in the tree, or click Cancel to abort.

Using folders is convenient, and sometimes necessary, when adding industry standard schema file sets such as the OAGIS schemas.

For example: in OAGIS schemas, there are 60 schema files that are linked together (in that they include each other). Since these includes use relative folder references, it is necessary that if you are adding a schema from the BODs directory, you must have already created a BODs directory, since some relative references go up two levels ../../ and then descend into another folder. Included or imported schemas and their folders are created automatically, if necesssary. However, going up two levels from the root of schemas is not possible.

To delete a folder, right click on the folder name and select Delete Folder from the context menu. This will delete the folder, all sub folders and all schemas contained in that subtree.

Delete All Schemas

To delete all schemas in the schema repository, right click on the SCHEMAS icon in the left pane of the Configuration tab to display the context menu, and select Delete All Schemas . A dialog box is displayed to confirm deletion. Click OK to confirm deletion of all schemas and schema folders in the schema repository, or click Cancel to abort. If any of the schemas being deleted are in use (attached to a root), then they cannot be deleted.

Delete a Schema

To delete a schema, right click on its schema icon in the left pane of the Configuration tab to display the context menu, and select Delete Schema. A dialog box is displayed to confirm deletion. Click OK to confirm or Cancel to abort. If the schema is in use (attached to a root), it cannot be deleted.

Refresh Schemas

It is often necessary to refresh the schema view to see schemas added by other users to the schema repository. To refresh the view of schemas, right click on the SCHEMAS icon in the left pane of the Configuration tab to display the context menu, and select Refresh .

Schemas as Resources

All schemas that are added are automatically made into XStreamDB resources under the "SysData/SysSchema" parent. This allows them to be accessed from the XStreamDB WebDAV driver or XdbWeb.

Display a Schema

If you left click on any schema under the SCHEMAS icon, or any schema under any schema folder, it will be displayed in two sections in the right pane of the Configuration tab.

The left section lists all the root elements under the selected schema. By clicking on a root element, it will be displayed in tree format in the right section. The screenshot below shows a display of the "Book.xsd:book" schema.

Security

The XStreamDB security system is concerned with authentication and authorization. Authentication is the validation of a user's credentials before that user can access the XStreamDB server. In the Explorer application, this is evidenced by the user logon dialog which is displayed at the time the Explorer is started. Authorization is established by determining permissions from resource access control lists (ACLs). For a detailed description of the XStreamDB security system, see the Security subsection of the Reference Guide. Note: You must have the required permissions to perform any security operations.

Users

Displaying Users

To display users in the XStreamDB server, left click on the USERS icon in the left pane of the Configuration tab. The users will be displayed in a table on the right pane of the Configuration tab.

Creating Users

To create a new user, right click on the USERS icon in the left pane of the Configuration tab, then select New User from the context menu. A dialog box will be displayed. Complete the required information and click OK to continue or Cancel to abort. If Ok was selected, the new user will be displayed in the table on the right pane of the Configuration tab.

Modifying User Passwords

To modify a user password, display the users in the right pane of the Configuration tab, as described above. Right click on the user and select Change Password . Enter the new password in the fields provided and select OK to continue or Cancel to abort.

Adding a User as a Member of a Group

To add a user as a member of a group, display the users in the right pane of the Configuration tab, as described above. Right click on the user and select Member of . A dialog box will be displayed listing all groups the user is currently a member of.

Selecting the Add button will display a further dialog box listing all groups in the XStreamDB Server.

Select which groups the user is to be made a member of, click Add , then click Ok . This will return you to the original dialog. Select Ok to continue or Cancel to abort.

Deleting Users

To delete an existing user, display the users in the right pane of the Configuration tab, as described above. Right click on the user and select Delete User . A confirmation dialog box opens. Click Yes to proceed or No to abort.

Groups

Displaying Groups

To display groups in the XStreamDB server, left click on the GROUPS icon in the left pane of the Configuration tab. The groups will be displayed in a table on the right pane of the Configuration tab.

Creating Groups

On the Configuration tab, under the Server icon, there is a GROUPS icon. If you click on the Groups icon, the popup menu will include an entry for New Group. Clicking on the New Group menu selection will display a dialog in which the group can be defined as well as the user members of the group.

Adding a Member to a Group

To add a member to a group, display the groups in the right pane of the Configuration tab, as described above. Right click on the group and select Members . A dialog box (below left) will be displayed listing all members within the selected group. Selecting the Add button will display a further dialog box (below right) listing all users in the XStreamDB Server. Select which users are to be added as members of the group, click Add , then click Ok . This will return you to the original dialog. Select Ok to continue or Cancel to abort.

Deleting Groups

To delete an existing group, display the groups in the right pane of the Configuration tab, as described above. Right click on the group and select Delete Group . A confirmation dialog box opens. Click Yes to proceed or No to abort.

Permissions

Modifying User and Group Permissions

Permissions are used to control user access to resources. There are five types of permissions that can be applied to a single resource:

  • Create - Controls whether new objects can be created within the resource.
  • Read - Controls view access to the resource
  • Update - Controls ability to modify an existing resource
  • Delete - Controls ability to remove the resource
  • Permit - Controls whether a user or all users within a group can modify permissions.

The XStreamDB Explorer allows these permissions to be applied at different levels . Permission settings may be overridden at any lower level. Permission levels currently supported from most broad to most specific are:

  • Server
  • Database
  • Root
  • Trigger
  • Module
  • Document

The permissions dialog is accessed by right clicking on an object from one of the level categories above, for example Database or Root. From the right click menu select User Permissions or Group Permissions . Next you must select a user or group from the list displayed in the permissions dialog by clicking on their name. This is the user/group for which you are setting permissions. Then you click on the Edit Permissions button to view the permissions matrix for the user/group that you selected.

You can then modify entries in the permission matrix and, when your changes are complete, click on the Apply button. The effect of your permission settings after taking into consideration your current settings and the settings of all containing objects at a higher level, can be seen in the effective Permissions column. For example: for all documents in the Book root, the administrator user has effective Create, Read, Update, Delete and Permitting (CRUDP) permissions. Lack of permission on all of these would be -C-R-U-D-P. Click on the CLOSE button to exit the permissions dialog.

Querying a Database

XQuery statements can be executed from a Statement Tab. You can have multiple statement tabs opened at any given time, and they are labelled (by default) "Statement{n}", where {n} is a sequential number. The label may be changed by right-clicking on the tab and selecting "Rename".

The Statement Tab

From the Statement tab you can:

  • Construct and run queries on the XStreamDB Server, and view the results
  • Edit XML documents using the Explorer Editor
  • Save the resultset of a query to your local hard disk
  • Delete a specific document from a Root. (This functionality is only available when the resultset consists of document nodes. Note: Depending upon your permission settings, you may not be allowed to perform this operation.
  • Set user and group permissions on a specific document. (This functionality is only available when the resultset consists of document nodes. Note: Depending upon your permission settings, you may not be allowed to perform this operation.
Statement Toolbar Icons

The toolbar icons relevent to the Statement tab are identified below:

Database Pane

The Database pane is at the top of the Statement tab on the left side and has the title PathBuilder . This is a list of all available databases for the currently connected Server. Clicking on the plus sign + on the left of a database name will expand the view to include all of the roots defined within the selected database.

Schema Display

The Schema Display is accessed by right clicking on a root in the Database pane and selecting Display Schema from the context menu.

Note: This option is only accessible if a schema has previously been associated with a Root.

Query Statement Pane

The Query Statement pane is located immediately below the Database pane. This is where queries are entered. Once a query is entered in this pane it can be executed by clicking on the Execute Query Button.

History Pane

The History pane is located immediately below the Query Statement pane. This is where previously executed queries are logged. Once a query is executed, it is saved to a history log, and is displayed at the bottom of the Short Form History windows (left side). If the statement is displayed in red, it indicates that that errors occurred when executing the query. The right side of the history pane is used to display the query in its entirety. Right clicking in either history pane provides a popup menu which allows the selected statement to be placed in the Query pane, ready to be executed.

Note: The Explorer comes pre-configured with a number of queries on the sample databases.

Results Pane

The Results pane is located in the bottom left of the Statement tab. This is where output from the last query executed is displayed. The contents of the resultset XML are shown in a tree control which can be expanded and collapsed by clicking on the plus + and minus - signs to the left of each tree item that contains child items.

Initially, only the first 50 results per query are retrieved. Additional groupings of 50 results can be obtained by clicking on the "play" button at the bottom of the Results pane or fetch all using the "play to end" button. The limit per request is initially set to 50 results. However, this number may be modified directly by typing a new value into the "Select Next" edit box. Multiple retrievals performed in this way, and based on the same original query, are cumulative. Thus, if you retrieve 20 results three times, there will be 60 result entries held in the Results pane.

Note in the above graphic the document nodes, for example: 1-0-0. If you right click on this graphic you can:

  • Edit: Launches an editor described below.
  • Delete: Deletes the current document.
  • Save: Saves the document to your local disk.
  • User Permissions: Sets user permissions for this document.
  • Group Permissions: Sets group permissions for this document.
Xml Display Pane

The Display pane is located on the bottom right of the Statement tab. This is where the XML is displayed for the currently selected result (in the Results pane to the left) is placed.

Sample Queries

Here are some selected queries. Many more can be found in the Quick Statements section of the User Guide. As well, Explorer history is preloaded with quite a few queries.

Sample 1: PersonDB Database

Query

for $doc IN Root("/PersonDB/Person") 
where $doc/Person/FirstName = "Frank" 
   and $doc/Person/City LIKE "P_R%" 
return $doc

Result

<Person Id='11' Active='true'>
  <!--firstname comment-->  
  <?--proc instrn--?>
  <FirstName> Frank </FirstName>
  <LastName> Crowe </LastName>
  <City> Paris </City>
  <BirthDate> 1960-05-30T05:00:00 </BirthDate>
  <Age> 67 </Age>
  <StockValue> 826.8 </StockValue>
</Person>

Sample 2: BookDB Database

Query

let $people := count(Root('/PersonDB/Person')) 
return <Population>{ $people }</Population>

Result

<Population> 100 </Population>

Explorer Editor

The XStreamDB Explorer is equipped with an internal XML Editor, which can be used to edit XML documents. It can be accessed:

The Editor has all basic functionality, including automatic tag completion and indentation, and block indentation.

Note: If a schema has been associated with the XStreamDB database root where the XML document is stored, schema validation will be performed at the time the edited XML document is saved back to the XStreamDB server.

Viewing Server Log Files

XStreamDB Explorer creates a log file each time it is run. These log files are accessible from within Explorer by clicking on the Log Tab.

Once the Log Tab is displayed, clicking on an individual log entry in the left pane causes the log file to be loaded and displayed in the right pane.

Managing Resources

From the Resources tab you can:

XStreamDB encompases the notion of categories, and resources within those categories. Resource definition and management involves mapping XStreamDB documents to a structure similar to a file system, which can be addressed via URLs, or can be checked out to folders and files in the operating system. Once resources are defined in XStreamDB, documents can be accessed and edited over the Internet using the fully secure XStreamDB WebDAV Java Web application. More discussion on the WebDAV Web application is contained in the XStreamDB User Guide.

The Resources tab includes a simple resource checkin/checkout facility. Once resources are defined, they can be moved to the file system and back again in a fashion similar to a source control system. For example: Get , Checkout and Checkin are supported.

Below is the resource management tab in the explorer with the /BookDB/Book category selected in the left pane and the contents of that category shown in the right pane.

Moving Resources to the File System

Often it is convenient to be able to work on documents offline when you are not connected to a network. For this reason, the XStreamDB explorer supports moving resources from the database to the client machine file system and back again. Explorer uses a resource Get, Checkout and Checkin system familiar to people who have used source control systems such as Microsoft SourceSafe or CVS. As well, files can be copied to the resource system using the Add XML Files or Add Binary Files option from the right-click popup menu (see diagram below).

Binary Resources

Binary content such as .jpg, .gif, .doc, files, can be added to XStreamDB as resources and subsequently referenced using URLs. Just right click on the category and use the add binary files menu item shown below to add a binary file.

Note: A mime type will be defaulted according to the file extension.

Populate by Query Filter

Note the Set Query Filter and Populate By Query menu items above. These are used to populate a category from documents already in the root corresponding to the category. What you enter for Set Query Filter is text that becomes a WHERE clause that will select certain documents.

For example, the $doc/Person/City="Paris" below becomes a WHERE clause in the underlying query that populates this Category. To do the actual populate, you must also select the Populate By Query menu item. As well, your query filter is remembered for further populates.

Advanced Usage

One problem with populate is that meaningful names do not show up for your documents. If you have a meaningful name in the data, then you may want to use a custom query in the statement window to populate. The example below is somewhat complex because it is creating new html resources from XML resources using XSL transformation. The thing to bear in mind, however, is the use of the GetXMLResourceText function since it creates the correct XML document for insertion into SysDocument so you are sure you don't corrupt the resource mechanism offered in XStreamDB. If you do corrupt the mechanism you can recover by deleting the SysDocument and SysCategory roots from your database�this will remove all your resource information but will leave your content in their respective root.

LET $xdoc := Root("/reference/temp")
LET $xslDoc := Root("/reference/publish")[@id = "journalist"]
RETURN
  LET $doc := XSLTransform($xslDoc,$xdoc) 
  LET $docId := INSERT DOCUMENT $doc INTO "/reference/html"
  LET $length := TextLength($doc)
  LET $res := GetXMLResourceText("/reference/html","reference.htm",$docId,$length)
    RETURN
      INSERT DOCUMENT $res INTO "/reference/SysDocument"

Glossary

Key terms and concepts are described here.

Term Description
Database The storage medium for collections ("Roots") of documents. A database corresponds to a single file on disk and usually has the extension 'XD'.
Document Well formed XML, whether it resides in the database or is accessed via a URL. May or may not begin with an XML declaration.
Index An efficient lookup mechanism that can be defined over a collection of documents (or Root).
Module A user defined library of stored functions under a common namespace. Stored functions in a module execute faster because they are preloaded, and the query plan is already prepared.
Result Set A database concept that allows effective management of results returned from the XQuery Engine.
Root An abstraction that facilitates the management of collections of documents within the database.
Schema A mechanism that defines what the valid XML form may be for an associated XML file. See W3C Schema for more information.
Trigger An XQuery statement that is executed when a document is inserted, updated or deleted in a Root.
Type Checking Verification of correct type usage in an XQuery statement, either statically, before a query is executed, or dynamically, during the execution of the query. This requires an associated schema or DTD file.
Validation The process of ensuring that a particular XML instance satisfies the definitions and constraints as specified in the associated DTD or Schema file.
XPath The XML Path language as defined by the W3C in this document: W3C XPath .
XQuery The XML Query language as defined by the W3C in this document: W3C XQuery .

Using WebDAV

Introduction

WebDAV (Web-based Distributed Authoring and Versioning) is a protocol for accessing and manipulating files and folders in remote systems as Internet resources referenced by URIs. Documents in XStreamDB can be exposed as Internet resources and accessed using a WebDAV client.

Examples of WebDAV clients include Web browsers, operating system file explorers (e.g. Windows, MacOS), and collaborative authoring applications.

For more information on WebDAV, visit www.webdav.org .

Accessing Resources

Before resources can be accessed via WebDAV they must be defined. Resources can be defined using the API, the scripting tool, or most easily using the XStreamDB Explorer .

The Resources tab above shows a set of XML resources on the right that are contained in the /BookDB/Book category. For example, the Graph_Representations_of_Structures.xml document would be served up under the XDB WebDAV Web application using the resource {scheme}:{host}/BookDB/Book/Graph_Representations_of_Structures.xml, where scheme is http and host is, for example, //www.bluestream.com .

Example editor applications used with XStreamDB resources and the WebDAV Web application are XMLSpy, from Altova, and XMetaL from Blast Radius. XMLSpy is more of an XML workbench; whereas, XMetaL is an XML editor that has richer visual editing capabilities.

As well as editors accessing the database, browsers can access resources directly.

Accessing WebDAV from XMLSpy V5

Start up XMLSpy and do the following:

  • Choose Project/Add External Web Folder to Project.
  • In the "Server URL" field enter your {scheme}:{host}. This should point to a running version of TomCat where WebDAV is mounted as the ROOT servlet such as in the install, for example, http://www.bluestream.com:8080. or http://localhost:8080 if you are using your local machine.
  • You will be prompted for a username and password. Use a valid XStreamDB user name and password�administrator and goxmldb will work by default.
  • The bottom pane will display your resource collections.
  • Choose a collection, and then press OK.
  • The folder you chose will show up in the project window of XML Spy, ready for editing.

If documents you edit in XMLSpy from WebDAV use relative URIs like /SysData/SysSchema/myschema.xsd then those will also be retrieved by XMLSpy from the XStreamDB server since schemas in XStreamDB are also resources.

Mounting Resources as a Windows Folder

This explanation is based on Windows 2000 Professional.

  • Under a Windows folder view or Windows file explorer, right click on "My Network Places".
  • Choose, Map Network Drive.
  • At the bottom of the "Map Network Drive" dialog choose, "create a shortcut to a Web Folder or FTP Site".
  • You will be prompted for the URL of the WebDAV server: for example, http://localhost:8080.
  • After that you will be prompted for a username and password as setup on the XStreamDB Server. By default administrator and goxmldb works.
  • Then you will be prompted for a name for this Web folder, for example, XDBWebFolder.
  • Once this is done, you are sometimes prompted for the username/password again and then your folders will be made available through Windows.

Note: In order to Edit files in a Windows Web Folder it is necessary to have the Editor WebDAV enabled. XMetaL 4.0 is such and editor and others are becoming available. Other Windows applications tend to only allow read access or sometimes no access to the file being accessed.

Tips and Traps

Here are a few tips and Traps regarding using WebDAV.

URI Planning

At Bluestream we found that designating all external URIs to resources as having /xdbres/ as a prefix was useful because it allows resource accessing technology to be plugged into other Web applications. In order to get this to work with WebDAV you would have to mount the WebDAV Web application war file at /xdbres not at the ROOT as it ships. This applies to XdbWeb as well. XdbWeb is similar to WebDAV except it is for accessing and tranforming resources. We have found that mounting the XdbWeb application at {host}/xdbres/...resourceId is useful. Obviously, both WebDAV and XdbWeb cannot be on the same server at {host}/xdbres.

XStreamDB Client API

Introduction

XStreamDB has a Client-Server architecture, so most client API calls are serviced remotely at the server with any results being returned to the client once the server completes the call.

The XStreamDB client API is broken down into two "sub-APIs". The first, and most important, is the JDBC like Statement functionality API. The second "sub-API" contains system configuration functionality.

Statement Functionality

The primary interfaces required when using the Statement API are:

All processing is performed by executing XQuery statements that run on the Server. In XStreamDB, there are two flavours of XQuery statements, the XStatement and the XPreparedStatement. The diagram below illustrates the relationships between the primary objects within the Client API.

Database System Object Manager

The Database System Object manager (interface: DSObjectMgr) provides read-only access to database system objects and their properties.

As well, some update capability is provided especially with respect to the SchemaMgr and the ResourceMgr.

The diagram below illustrates how the DSObjectMgr interface is obtained from a connection and what the key objects are once that DSObjectMgr is obtained. Note that the DatabaseTree is a tree that contains not only the Database object but collections of all the sub objects to a database.

System Initialization

Use of the XStreamDB Client API must always follow a proper init, process, shutdown cycle. The code fragment below illustrates this concept. Note that it is recommeded to always place the call to shutdown() in a finally clause to ensure it is invoked at termination.

          try 
{
  SystemManager.
          init()
          ;
  //  processing code goes here
  ...
}
catch(throwable t)
{
  // handle error cases here
}
          finally
          {
  SystemManager.
          shutdown()
          ;
}
        

Obtaining a Server

The first step towards running a query is to obtain a Server object. This is done by using the getServer() method on the SystemManager object as shown below.

          Server srv = SystemManager.
          getServer
          ("MyServer");
        

The parameter to getServer() is the 'name' of the server that is defined in the XDBClientConfig.xml file in the Client/conf directory. A simple example of this client configuration file is shown here.

          <?xml version="1.0" ?>
<XDBClientConfig>
  <Servers>
    <Server 
        name="
          MyServer
          " 
        host="
          localhost
          " 
        port="
          1223
          " />
  </Servers>
  <InstallType type="ClientServer" />
</XDBClientConfig>
        

Note: The 'host' and the 'port' entries will likely need to be changed to suit your installation environment. The example shown here defines a Server ("localhost") that is running on the same computer as the Client application. It is also using the default port ("1223") for XStreamDB Server. This port number may be changed as necessary, but the ports used by Client and Server must always match.

Note: In a WebApplication is is advisable to make a Server object a static singleton since connection pools are held for a server. Otherwise, connection pooling will not be in effect reducing performance.

Opening a Connection

Once a Server object has been obtained, the next step is to open a connection through which the Client can communicate with the Server. It may be helpful if you think of the Server object as a proxy for the XStreamDB Server process which may be physically running on a machine in another building or another city.

The Server object acts as a stand-in for the remote Server process. The Server object still requires a connection to the remote Server because it is the remote Server who actually does the heavy work of processing the XQuery statement and formulating results.

To open a connection requires that the Client be authenticated to the Server. In other words, only Users known to the Server are permitted access. Obtain a valid User name and password and then use the following code fragment to create a connection to your XStreamDB Server.

Note it is recommended that XConnections be closed when they are no longer required. This ensures that connections are properly shutdown and that resources are freed for reuse.

          // use user + password that is valid on your Server
AuthenticationInfo ai = new
          SimpleAuthInfo
          ("fred", "mypassword"); 
try
{
          XConnection
          xc = srv.
          getConnection
          (ai);
  // use the connection to execute some queries...
  ...
  xc.
          close
          ();
}
catch(Throwable t)
{
  // handle error 
}
        

Notice that the getConnection() method returns an XConnection object. It is this object that allows you to execute statements against the Server.

Using Transactions

The code fragment below illustrates the use of transactions to wrap statement execution. This allows changes to the database to be deferred until their outcome is known to be successful. No alteration of the database occurs until the commitTransaction() method is invoked. If the server throws an XDBException for any reason then the transaction in progress is rolled back. However, you may need to rollback the transaction yourself should your own methods fail unexpectedly. For example, if myOtherOperation() below fail and throw an exception, that exception will be handled in the catch (Throwable t) java code and the connection's transaction is rolled back using "rollbackTransaction().

          AuthenticationInfo ai = new SimpleAuthInfo("fred", "mypassword"); 
try
{
  XConnection xc = srv.getConnection(ai); 
  xc.
          beginTransaction
          ();
  XStatement stmt = xc.createStatment(...);
  xc.execute(stmt, ...);
  myOtherOperation();
  xc.
          commitTransaction
          ();
}
catch(XDBException xdbEx)
{
   // do nothing since XStreamDB server will automatically rollback these
}
catch (Throwable t)
{
  if (xc.isTransactionActive())
    xc.
          rollbackTransaction
          ();
}
        

Creating an XQuery Statement

Once an XConnection has been opened, XStatements can be created quite simply as shown below.

          XConnection xc = ...
          XStatement
          xqStmt = xc.
          createStatement
          ();
        

Executing an XQuery Statement

Now everything is in place to execute an XQuery statement. At this point, we must associate the XQuery statement we wish to execute with the XStatement object as is demonstrated below. A simple query is: Root('MyDB:MyRoot') which returns all of the documents held under the root specified.

          try
{
  XConnection xc = ... xc.beginTransaction();
  XStatement xqStmt = xc.createStatement();
  String myQuery = "Root('/MyDB/MyRoot')";
          XResultSet
          rs = 
      xqStmt.
          execute
          (myQuery,
          XStatement.SF_DEFAULT
          );
  // extract the results from the XResultSet
  ...
  xc.commitTransaction();
}
catch(...)
{
}
        

Notice the second parameter to the execute() function, XStatement.SF_DEFAULT . This flag tells the Server how the result set should be setup. The table below describes the most common XStatement flag values and when to use them.

Flag Name Description
SF_TRAVERSE_ALL

This option causes all the results to be traversed automatically and thus there is no ResultSet returned.

This is useful for DML statements, such as CREATE DATABASE, DROP ROOT etc. which typically would not return a result in any case. If you know in advance that your query will not yield any results, or if you do not care to retrieve them use this flag. If you do not use this flag you MUST traverse your results until false is returned, otherwise your statement will not be fully executed.

SF_DEFAULT

This option configures the result set to that each result can be retrieved individually. This allows results to be incrementally retrieved as required.

This is commonly used when the total number of results is unknown and you want to retrieve only a few results (perhaps 20) at a time for display purposes. This is a very flexible approach that permits the query to be aborted part way through if it is no longer required. A query may be aborted by invoking close() on the XStatement object.

Retrieving Results

An executed statement returns an XResultSet that represents all the results from the query. The code fragment below illustrate how to retrieve each result individually.

Some working code samples can be found in the Client/samples/console directory. Most of the code fragments in this document were based on Query.java .

          try
{
  XStatement xqStmt = xc.createStatement();  
  String myQuery = "Root('/MyDB/MyRoot')";
          XResultSet
          rs = 
          xqStmt.
          execute
          (myQuery,
          XStatement.SF_DEFAULT
          );
  if (rs != null)
  {
    FlexStringBuffer fsbTemp = new FlexStringBuffer();
    rs.
          beforeFirst
          ();
    int i = 1;
    while (rs.
          nextValue
          ())
    {
      fsbTemp.setLength(0);
      rs.
          fsbGet
          (fsbTemp, false /*append*/);
      if (fsbTemp.length() > 0)
      {
        System.out.println(String.valueOf(i)+". "+fsbTemp);
      }
      i++;
    }
  }
  // release the statement once it is no longer required
  xqStmt.
          close
          ();  
}
catch(...)
{
}
        

XQuery Statements

Statements are text blocks which are passed to the XStreamDB server for execution. Most statements will be standard XQuery statements but some will use XStreamDB XQuery extensions.

Starting Concepts

Server, Database, Root, Document

An XStreamDB server hosts one or more databases. Each database is composed of any number of user definable roots. A Root is a collection of documents, similar to a table in a relational database. Within each root can be zero or more documents. A document must be well formed XML but can optionally contain the XML prolog, XML version, and DOCTYPE directives. There is no reason, however, why you can't store fragments of XML in XStreamDB as documents, as long as these fragments are well formed.

Query Examples

Simple

A few simple starting examples.

This is one of the simplest queries possible in XQuery. Any XQuery expression is a valid XQuery statement. In this case, "2" is a valid primitive expression which evaluates to 2.

Query:

2

Result:

2

more results

This query shows simple arithmetic with parenthesis. Note that the output of this query is not well-formed XML. The XQuery data model allows the output of a query to be not well-formed XML.

Query:

(1+1)*25

Result:

50

more results

Documents

These examples show document access from a root.

An XML document is modelled in XQuery as a tree consisting of a single document node, with a root element child and then that root element has subsequent child elements as necessary. This query returns all the root elements in the root BookDB/Book.

Query:

Root("/BookDB/Book")/book

Result:

<book year = '1994'>
    <!--this is the 1st book-->
    <title>
      TCP/IP Illustrated
    </title>
    <author>
      <last>
        Stevens
      </last>

more results

XPath

XPath expressions are crucial to XQuery

An XPath expression is a type of XQuery expression. XPath expressions allow you to select values by specifying their "path" within a document or set of documents. This query shows the selection of the city elements in all the documents in the root Person.

Query:

Root("/PersonDB/Person")/Person/City

Result:

<City>
    Paris
  </City>
  <City>
    London
  </City>
  <City>
    New York
  </City>

more results

As well as selecting path values, you can specify predicates (conditions) within XPath. This query returns only those Persons who live in "Paris". Note in the query below that what gets returned is the path expression to the left of the '[' bracket. This bracket can be placed anywhere in the path.

Query:

Root("/PersonDB/Person")/Person[City = "Paris"]

Result:

<Person Id = '1' Active = 'true'>
    <!--firstname comment-->
    <?proc instrn ?>
    <FirstName>
      John
    </FirstName>
    <LastName>
      Doe
    </LastName>

more results

XPath expressions can also access attribute values. The expression below accesses the year attribute in the book element. Note: XQuery uses the abbreviated XPath syntax. In the unabbreviated syntax the expression below would read Root('/BookDB/Book')/child:book/attribute:@year.

Query:

Root('/BookDB/Book')/book/@year

Result:

year='1994'
  year='1992'
  year='1999'
  year='2000'

more results

FLWOR

FLWOR (flower) stands for for, let, where, order by and return. The FLWOR expression is one of the main constructs introduced by XQuery. Each of the for, let, where, order by and return parts are "clauses" and are not complete expressions in themselves.

This query returns all the Persons who live in Paris. This query is identical in meaning to the previous XPath example: Root("/PersonDB/Person")/Person[City = "Paris"]. Note: the for below is similar to for loops in other languages. for $d in Root("/PersonDB/Person") can be read as, for each document in root Person, execute the rest of the FLWR expression, binding $d to each document in Person.

Query:

for $d in Root("/PersonDB/Person") 
where $d/Person/City = "Paris" 
return $d

Result:

<Person Id = '1' Active = 'true'>
    <!--firstname comment-->
    <?proc instrn ?>
    <FirstName>
      John
    </FirstName>
    <LastName>
      Doe
    </LastName>

more results

The let clause in FLWR can be used for a number of reasons. This query shows let being used for a simple variable assignment. This query returns the FirstName of all the persons living in Paris. let is typically used in more complex queries - see Advanced FLWR queries.

Query:

for $d in Root("/PersonDB/Person") 
let $fn := $d/Person/FirstName/text() 
where $d/Person/City = "Paris" 
return $fn

Result:

John
  Frank
  George
  Russ
  Paul
  Leif
  Michael
  Jim
  Peter

more results

Predicates

Predicates are a way of restricting the set of data.

As shown in previous queries, it is possible to restrict the sequence of data returned by a FLWR statement by using a where clause, or in the case of XPath a predicate within square brackets. This query further shows the use of predicates. This query returns all the persons with first name John that live in Paris.

Query:

for $d in Root("/PersonDB/Person") 
where $d/Person/FirstName = "John"  
   and $d/Person/City = "Paris" 
return $d

Result:

<Person Id = '1' Active = 'true'>
    <!--firstname comment-->
    <?proc instrn ?>
    <FirstName>
      John
    </FirstName>
    <LastName>
      Doe
    </LastName>

more results

This query shows the use of not, which is a function and has the effect of converting true to false and false to true. This query returns all the cities with people named John, but not those in Paris.

Query:

for $d in Root("/PersonDB/Person") 
where $d/Person/FirstName = "John"  
   and not($d/Person/City = "Paris") 
return $d//City/text()

Result:

London
  New York
  Toronto
  Sydney
  Vancouver
  Spuzzum
  Okotoks
  Calgary
  Medicine Hat

more results

Tag state, XQuery state

When XQuery is parsed the parser is either in Tag state or XQuery state. The allowable grammar for each of these states is different.

This query shows the use of element constructors in XQuery. In this query the entire output of root /PersonDB/Person is placed in the <Result> tag. Note: The left angle bracket "<" causes a shift of the XQuery parser into tag state and it is only through the use of left curly "{" that you can shift back into XQuery expression state.

Query:

<Result> 
   {Root("/PersonDB/Person")/Person} 
</Result>

Result:

<Result>
    <Person Id = '1' Active = 'true'>
      <!--firstname comment-->
      <?proc instrn ?>
      <FirstName>
        John
      </FirstName>
      <LastName>
        Doe

more results

order by and distinct

This query shows the use of element constructors in XQuery. In this query the entire output of root /PersonDB/Person is placed in the <Result> tag. Note: The left angle bracket "<" causes a shift of the XQuery parser into tag state and it is only through the use of left curly "{" that you can shift back into XQuery expression state.

Query:

for $p in Root("/PersonDB/Person")/Person 
order by $p/FirstName  
return $p/FirstName/data()

Result:

Frank
  Frank
  Frank
  Frank
  Frank
  Frank
  Frank
  Frank
  Frank

more results

Give me a list of distinct cities where persons live.

Query:

for $c in distinct( 
   Root("/PersonDB/Person")/Person/City/text()) 
return $c

Result:

Calgary
  London
  Medicine Hat
  New York
  Okotoks
  Paris
  Spuzzum
  Sydney
  Toronto

more results

Full Text Search

Search on words.

This query shows the full contents of the books root.

Query:

Root('/BookDB/Book')

Result:

<book year = '1994'>
    <!--this is the 1st book-->
    <title>
      TCP/IP Illustrated
    </title>
    <author>
      <last>
        Stevens
      </last>

more results

This query returns only those books with the word Unix in its title. Note, the first part of the match expression is the source to search on. The second part of the match is the using clause which specifies the type of match, either contains, proximity or has phrase. In the example below we use the contains clause.

Query:

for $d in Root('/BookDB/Book') 
where match $d using [/book/title contains "Unix"] 
return $d

Result:

<book year = '1992'>
    <!--this is another book-->
    <title>
      Advanced Programming in the Unix environment
    </title>
    <author>
      <last>
        Stevens
      </last>

more results

This query returns only those books with the word good and discussion in its review. Note the words discussion and good are spaced separated. What this means is "discussion" and "good" must occur in any order.

Query:

for $d in Root('/BookDB/Book') 
where match $d using [/book/review contains "discussion good"] 
return $d

Result:

<book>
    <!--this is another book-->
    <title>
      Data on the Web
    </title>
    <price>
      34.95
    </price>
    <review>

more results

This query will return all documents that contain the word "data" in any path "//*". Each document will be scored according to how relevant it is to the word "data" If data is not contained in the document it will be given a score of zero and the where $score > 0 clause will filter it out. As well, the results are ordered by score descending to produce a "google" style results page. It is expected that a result is further selected by the user with a subsequent GetDocument(-- docid--) kind of query. SNote the words discussion and good are spaced separated. What this means is "discussion" AND "good" must occur in any order.

Query:

for $doc in Root("/BookDB/Book") 
let $score := score $doc using [//* contains "data"] 
where $score > 0 
order by $score descending 
return  
<hit  
   title='{$doc/book/title}'  
   id='{GetDocId($doc)}'  
   score='{$score}'> 
</hit>

Result:

<hit title = 'Data on the Web' id = '1$BookDB:Book$2-14-0' score = '0.65036345'>
  </hit>
  <hit title = 'Data on the Web' id = '1$BookDB:Book$2-13-0' score = '0.65036345'>
  </hit>
  <hit title = ' Data on the Web' id = '1$BookDB:Book$2-4-0' score = '0.38411513'>
  </hit>
  <hit title = 'Data on the Web' id = '1$BookDB:Book$2-12-0' score = '0.38411513'>
  </hit>
  <hit title = 'Data on the Web' id = '1$BookDB:Book$2-3-0' score = '0.38411513'>

more results

text() and data()

text() and data() are primitive value accessors.

Sometimes you want to return an element tag and its value, othertimes you want to return the text of the tag. Using the text() accessor allows you to extract the text from the tag. This query will return the city text. Note: you can also use data() to extract the value of city. data() is a typed accessor, but it has the same effect as text() in most cases.

Query:

for $d in Root('/PersonDB/Person') 
return $d/Person/City/text()

Result:

Paris
  London
  New York
  Toronto
  Sydney
  Vancouver
  Spuzzum
  Okotoks
  Calgary

more results

Data Definition

Data definition covers creation of databases and roots as well as permission setting and schema association with a root. User definition, permission reading and schema add and access is not handled in statements but through the ServerConfigMgr part of the client API. SetDescription

Sometimes you want to return an element tag and its value, othertimes you want to return the text of the tag. Using the text() accessor allows you to extract the text from the tag. This query will return the city text. Note: you can also use data() to extract the value of city. data() is a typed accessor, but it has the same effect as text() in most cases.

Database create.

Query:

create database "/TestDB"

Root create.

Query:

create root "/TestDB/TestRoot"

Drop database.

Query:

drop database "/TestDB"

node update

Node update allows you to update any node within an XQuery variable. Through node update any XQuery variable can be updated by inserting, replacing and deleting elements, attributes and simple values. Often, in practice, this node update is used in conjunction with root update shown below to update the database. Node update can, however be used to simply change the results of the query as shown in these examples here.

Insert a company tag under each Person from Paris.

Query:

for $d in Root("/PersonDB/Person") 
let $newdoc :=  
   update $d using insert value <Company>Ford</Company> into $d/Person 
where $d/Person/City = "Paris" 
return $newdoc

Result:

<Person Id = '1' Active = 'true'>
    <!--firstname comment-->
    <?proc instrn ?>
    <FirstName>
      John
    </FirstName>
    <LastName>
      Doe
    </LastName>

more results

All of the people in Toronto have moved to Vancouver. For those persons with city Toronto, change the value to Vancouver.

Query:

for $d in Root("/PersonDB/Person") 
let $newdoc :=  
   update $d using replace value $d/Person/City/text() with "Vancouver" 
where $d/Person/City = "Paris" 
return $newdoc

Result:

<Person Id = '1' Active = 'true'>
    <!--firstname comment-->
    <?proc instrn ?>
    <FirstName>
      John
    </FirstName>
    <LastName>
      Doe
    </LastName>

more results

Similarily to the above query except we construct a new <City> tag wrapper.

Query:

for $d in Root("/PersonDB/Person") 
let $newdoc :=  
   update $d using replace value $d/Person/City with <City>Vancouver</City> 
where $d/Person/City = "Paris" 
return $newdoc

Result:

<Person Id = '1' Active = 'true'>
    <!--firstname comment-->
    <?proc instrn ?>
    <FirstName>
      John
    </FirstName>
    <LastName>
      Doe
    </LastName>

more results

Take the values from the FirstName and LastName and put them into a new tag called <Name>, replacing FirstName and LastName in the process. Note the use of the delete tag below.

Query:

for $d in Root("/PersonDB/Person") 
let $name :=  
   ($d/Person/FirstName/text()," ",$d/Person/LastName/text()) 
let $nd1 :=  
   update $d using  
      replace value $d/Person/FirstName with (<Name>{$name}</Name>)  
let $newdoc := update $nd1 using delete value $nd1/Person/LastName 
where $d/Person/City = "Paris" 
return $newdoc

Result:

<Person Id = '1' Active = 'true'>
    <!--firstname comment-->
    <?proc instrn ?>
    <Name>
      John Doe
    </Name>
    <City>
      Paris
    </City>

more results

Root Editing (update)

Root editing covers the insertion, replacing and deletion of documents in a root. Used in conjunction with tree editing and other features of XQuery, tree editing can be quite powerful.

Create a temporary database.

Query:

create database "/EditDB"

Create a temporary root for persons.

Query:

create root "/EditDB/EditPerson"

Copy person root. Note the use of the insert document expression.

Query:

for $d in Root("/PersonDB/Person") 
   return  
      insert document $d into "/EditDB/EditPerson"

Result:

1$EditDB:EditPerson$1-0-0
  1$EditDB:EditPerson$1-1-0
  1$EditDB:EditPerson$1-2-0
  1$EditDB:EditPerson$1-3-0
  1$EditDB:EditPerson$1-4-0
  1$EditDB:EditPerson$1-5-0
  1$EditDB:EditPerson$1-6-0
  1$EditDB:EditPerson$1-7-0
  1$EditDB:EditPerson$1-8-0

more results

Insert a company tag under each Person from Paris and replace each document in the database with this change.

Query:

for $d in Root("/EditDB/EditPerson") 
let $newdoc :=  
   update $d using  
      insert value <Company>Ford</Company> into $d/Person 
where $d/Person/City = "Paris" 
return  
   replace document GetDocumentId($d) with $newdoc

Result:

1$EditDB:EditPerson$1-0-0
  1$EditDB:EditPerson$1-10-0
  1$EditDB:EditPerson$1-20-0
  1$EditDB:EditPerson$1-30-0
  1$EditDB:EditPerson$1-40-0
  1$EditDB:EditPerson$1-50-0
  1$EditDB:EditPerson$1-60-0
  1$EditDB:EditPerson$1-70-0
  1$EditDB:EditPerson$1-80-0

more results

Query to ensure that the update was complete.

Query:

for $d in Root("/EditDB/EditPerson") 
where $d/Person/City = "Paris" 
return $d

Result:

<Person Id = '1' Active = 'true'>
    <!--firstname comment-->
    <?proc instrn ?>
    <FirstName>
      John
    </FirstName>
    <LastName>
      Doe
    </LastName>

more results

Query persons in Toronto.

Query:

for $d in Root("/EditDB/EditPerson") 
where $d/Person/City = "Toronto" 
return $d

Result:

<Person Id = '4' Active = 'true'>
    <!--firstname comment-->
    <?proc instrn ?>
    <FirstName>
      John
    </FirstName>
    <LastName>
      Doe
    </LastName>

more results

Delete all the persons from Toronto.

Query:

for $d in Root("/EditDB/EditPerson") 
where $d/Person/City = "Toronto" 
return delete document GetDocumentId($d)

Result:


          

more results

Query persons in Toronto.

Query:

for $d in Root("/EditDB/EditPerson") 
where $d/Person/City = "Toronto" 
return $d

Cleanup database.

Query:

drop database "/EditDB"

Function Modules

Functions modules allow you to define one or more query functions and store them in the database for future use. This allows for the modularization of queries as well as the sharing of queries across projects. Stored functions are pre-compiled to avoid the need to re-compile them every time they are invoked, making them faster than externally provided standard queries.

Create a module with 2 functions.

Query:

create module "TwoFunc" 
define function AddOne(xsd:integer $baseNum) returns xsd:integer 
{ 
   $baseNum+1 
} 
define function AddFour(xsd:integer $baseNum) returns xsd:integer 
{ 
   4+$baseNum 
}

Result:


          

more results

Use the functions.

Query:

import module namespace pre = "TwoFunc" 
let $sum := pre:AddOne(1) + pre:AddFour(12)  
return $sum

Result:

18

more results

Drop function module.

Query:

drop module "TwoFunc"

Result:


          

more results

Drop function module.

Query:

let $i := "2" 
   let $min := "10" 
   let $max := "25" 
   return 
   if ($i >= $min and $i <= $max )  
      then ("yes") else "no"

Result:

yes

more results

Data Types

XStreamDb supports numeric and string constants and support casting to the built in XStreamDb data types. As well, if W3C schema is provided for the root with data types then XStreamDb will use those data types as necessary

String compare: note string compare, not numeric.

Query:

let $i := "2" 
   let $min := "10" 
   let $max := "25" 
   return 
   if ($i >= $min and $i <= $max )  
      then ("yes") else "no"

Result:

yes

more results

Cast to make comparison of strings numeric.

Query:

let $i := "2" 
   let $min := "10" 
   let $max := "25" 
   return 
   if ($i >= cast as long ($min) and $i <= cast as long ($max) )  
      then ("yes") else "no"

Result:

no

more results

Numeric constants cause numeric compare.

Query:

let $i := 2 
   let $min := 10 
   let $max := 25 
   return 
   if ($i >= $min and $i <= $max ) then 
      ("yes") else "no"

Result:

no

more results

Building Web Applications

Overview

XStreamDB is an ideal application to use for providing documentation or other content in a Web environment. Since it is 100% Java and communicates via sockets, it fits perfectly into a networked environment, such as the Web. At its simplest, the Web is an excellent display medium. The scenario described