Table of Contents
Abstract
This appendix is a manual for Qizx/open, a cut-down open-source version of Qizx.
It is a summary of the relevant sections of the above Qizx Manual.
These short tutorials assume you have at least a basic knowledge of the XML Query language.
This section is a simplified version of the tutorial found in Chapter 4, Getting started.
To help experimenting and developing with XML Query, Qizx/open comes with two tools which make it easy to write and execute XML Query scripts:
A graphic tool featuring a simple XML Query workbench with which you can write and execute XML Query scripts, and view the results.
A command-line tool which can be used to execute XML Query script files.
Qizx Studio currently provides a basic environment for editing and running XML Query queries.
On Windows, the directory bin inside the Qizx distribution contains an executable qizxstudio.exe (or qizxstudio.bat), that can be started directly by a double-click,
On Linux or Mac OS X or other Unix, the shell script bin/qizxstudio can be started from a terminal or from a graphical file manager.
Note that when started from a console, Qizx Studio accepts command-line arguments, for example to directly load a XML Query script in the editor. See the reference documentation.
You should then see a window looking like this:
In contrast with Qizx, there is only one tab in Qizx/open Studio: "XQuery" for entering and running queries.
Let us try this query (which is the contents of the file qizxopen/queries/4.xq
):
(: Find all books written by French authors. :)
declare namespace t = "http://www.qizx.com/namespace/Tutorial";
declare variable $authors := collection("../../book_data/Authors/*.xml");
declare variable $books := collection("../../book_data/Books/*.xml");
for $a in $authors//t:author[@nationality = "France"]
for $b in $books//t:book[.//t:author = $a/t:fullName]
return
$b/t:title
Note that the directory docs/samples/programming/qizxopen/queries
contains the queries needed to illustrate this lesson.
Use the menu
→ to load the file mentioned above.Note that you can also save to a file a query that you have entered or edited in Qizx Studio.
There is an history that allows running again former queries, so it is not necessary to save intermediary experiments.
Then you can use the button Execute to run the query.
The query above uses relative paths for the collection()
function. Depending how you launched Qizx Studio, you might have to replace the relative paths by absolute paths, otherwise you will get an error like "empty collection ../../book_data/Authors/*.xml
".
After execution, we should obtain something similar to this:
Notice that, in the picture above, the display mode of the right-side view has been changed to "Data Model", by using the View combo-box. This makes it easier to see the Data Model structure.
The result sequence contains one item, which is a element t:title
whose string value is "Planet of the Apes
".
If for example we change the value "France
" to "US
" in the query, then we get a sequence of 8 items.
In the same directory there are a few other queries that you can also try.
The result items in the right-side view can be exported into a file using a button in the header. Notice that the resulting file will not in general be a well-formed XML document.
The Diagnostic view at bottom left contains messages, which can be simple information (execution times) or possible execution errors.
Compilation and execution errors have generally a link to the location in the source code. By clicking the link, the cursor moves to the location of the error in the editor view.
For more information about the editor and the query history, please see the documentation of Qizx Studio.
The shell script qizx
(qizx.bat
on Windows) is also located in the bin/
directory in the Qizx distribution. In the following we assume that this bin/
directory is in the PATH
environment variable.
In a terminal window, type the following command (the current directory is assumed to be docs/samples/programming/qizxopen)
:
qizx queries/4.xq
Results are displayed on the console (or standard output) by default. The option -out
specifies an output file. Serialization options can be used to specify the output format.
The details of option switches can be found in the tool reference qizx(1).
The API in Qizx/open is much simpler than in Qizx because it has not to deal with the management of XML libraries. This section is a simplified version of the tutorial found in Chapter 10, Programming with the Qizx API.
The code samples used to illustrate this chapter (class OpenQuery.java
) are found in the docs/samples/programming/qizxopen
directory. Files containing XQuery scripts are found in the docs/samples/programming/qizxopen/queries
sub-directory. These scripts are almost the same as those used in the Qizx tutorial, except that access to documents is performed through file paths instead of locations within an XML Library.
You'll need a recent version of ant, a Java-based build tool to compile and run the codes samples.
To create a XML Query session, we need a factory, which is an instance of the class XQuerySessionManager
. This class manages documents and XML Query modules, so it is recommended to use a single instance from which all sessions are created. The argument of the constructor is an URL used to locate XQuery modules: here it points to the current directory, but we could also use an HTTP URL pointing to a network server.
File currentDir = new File(System.getProperty("user.dir")); XQuerySessionManager sm = new XQuerySessionManager(currentDir.toURL()); XQuerySession session = sm.createSession();
If you have to handle large documents or many documents in a Qizx/open application, it can be useful to tune the size of the document cache. This cache keeps the last documents parsed, so it avoids reloading documents in different sessions. However the cache detects a modification on a document in a file and reloads it.
Reminder: in Qizx/open, documents are always parsed into memory before processing. The functions that load documents are doc()
and collection()
. They are documented in the last section of this appendix: Section 3, “Differences between Qizx/open and Qizx”.
Use XQuerySessionManager.setTransientDocumentCacheSize(int size)
to specify a size in bytes for this cache. You can also use the system property com.qizx.docpool.maxsize
(For example you would specify -Dcom.qizx.docpool.maxsize=100000000
on the command line).
Compiling and running a XML Query script is fairly easy:
Expression expr = session.compileExpression(script);ItemSequence results = expr.evaluate();
while (results.moveToNextItem()) {
Item result = results.getCurrentItem();
/*Do something with result.*/
}
First compile an XQuery expression using | |
Then evaluate the expression using | |
An Example ( (: Compute and return 2 + 3 :)
2 + 3 evaluates to an Example ( (: List all books by their titles. :)
declare namespace t = "http://www.qizx.com/namespace/Tutorial";
collection("../../book_data/Books/*.xml")//t:book/t:title evaluates to an |
The OpenQuery
class implements a simple command-line tool allowing to run queries.
Excerpts of OpenQuery.java
:
private static Expression compileExpression(XQuerySession session, String script, QName[] varNames, String[] varValues) throws IOException, QizxException { Expression expr; try { expr = session.compileExpression(script); } catch (CompilationException e) { Message[] messages = e.getMessages(); for (int i = 0; i < messages.length; ++i) { error(messages[i].toString()); } throw e; } if (varNames != null) { for (int i = 0; i < varNames.length; ++i) { expr.bindVariable(varNames[i], varValues[i], /*type*/ null);} } return expr; }
An XQuery expression can be further parametrized by the use of variables. Example ( (: List all books containing the value of variable $searched in their titles. :) declare namespace t = "http://www.qizx.com/namespace/Tutorial"; declare variable $searched external; collection("/Books")//t:book/t:title[contains(., $searched)]
|
Some queries may return thousands of results. Therefore, displaying just a range of results (e.g from result #100 to result #199 inclusive) is a very common need.
private static void evaluateExpression(Expression expr, int from, int limit) throws QizxException { ItemSequence results = expr.evaluate(); if (from > 0) { results.skip(from);} XMLSerializer serializer = new XMLSerializer(); serializer.setIndent(2); int count = 0; while (results.moveToNextItem()) { Item result = results.getCurrentItem(); System.out.print("[" + (from+1+count) + "] "); showResult(serializer, result); System.out.println(); ++count; if (count >= limit)
break; } System.out.flush(); }
| |
This being done, you still need to limit the number of |
In this lesson, we'll just show how to print the string representation of an Item
.
private static void showResult(XMLSerializer serializer, Item result) throws QizxException { if (!result.isNode()) {System.out.println(result.getString());
return; } Node node = result.getNode();
serializer.reset(); String xmlForm = serializer.serializeToString(node);
System.out.println(xmlForm); }
| |
| |
The |
Compile class Query
by executing ant (see build.xml
) in the docs/samples/programming/query/
directory.
Run ant run1 in the docs/samples/programming/qizxopen/
directory to perform this query:
(: Find all books written by French authors. :)
declare namespace t = "http://www.qizx.com/namespace/Tutorial";
for $a in collection("/Authors")//t:author[@nationality = "France"]
for $b in collection("/Books")//t:book[.//t:author = $a/t:fullName]
return
$b/t:title
You can execute all the queries by running ant run_all in docs/samples/programming/qizxopen/
.
Table A.1. Summary of functional differences between Qizx/open and Qizx
Qizx | Qizx/open | |
---|---|---|
Basic features of the XML Query language | yes | yes |
Optional features of the XML Query language: Modules, Full Axis | yes | yes |
Persistent compressed document storage | yes | - |
In-memory XML documents | yes | yes |
Indexed queries | yes | - |
ACID transactions, hot backup | yes | - |
Full-text search | yes | yes, but not indexed |
Unlimited database size | yes | - |
General XQuery extension functions | yes | yes |
XML Library handling extension functions | yes | - |
Join optimizations | yes | yes |
Java Binding | yes | yes |
Java API | yes | yes (cut down) |
Source code of applications, API and utilities | yes | yes |
Source code of the XQuery engine | - | yes |
In Qizx/open, the following elements are absent:
in package com.qizx.api: all classes whose name begins with 'Library
': Library
, LibraryMember
, etc,
in package com.qizx.api: interface AccessControl
and User
, class AccessControlException
,
package com.qizx.api.util.accesscontrol .
fn:doc ($path-or-URL
as xs:string)
as node()
The standard doc()
function of XQuery.
Parameter $path-or-URL
: This argument can be a simple file path or any URL supported by the Java run-time.
Returned value: a document node.
Example:
doc("../book_data/Authors/iasimov.xml") doc("http://www.axyana.com/qizx_tests/doc.cml")
fn:collection ($path
as xs:string)
as node()*
This is the standard collection()
function of XQuery, slightly extended.
Parameter $path
: This argument is a list of documents paths, separated by commas or semicolons.
A normal path (without wildcard characters) is treated as per the function fn:doc()
. So it can either be part of a XML Library, or be an external document (file or URL) parsed on the fly.
If a path contains the wildcard characters *
or ?
, it is treated as a file pattern and expanded. Attention: wildcard characters are currently accepted only in the file name, not in the path of the parent directory.
For example
can be expanded, while collection("/home/data1/*.xml;/home/data2/*.xml")
currently cannot be expanded (generates an error).collection("/home/*/*.xml;")
All of the documents must be accessible, or an error is raised.
If the expanded sequence of documents is empty, an error is raised.
Returned value: a sequence of document nodes.
Example:
collection("../book_data/Authors/*.xml;../book_data/Author blurbs/*.xhtml")