Appendix A. Qizx/open Manual

Table of Contents

1. Getting Started with Qizx/open
1.1. Writing and running queries with Qizx Studio
1.2. Running queries with the qizx command line tool
2. Programming with the Qizx/open API
2.1. Compiling and running the code samples
2.2. Creating a work session
2.3. Compiling and executing queries
2.3.1. Compiling and running the code of this lesson
3. Differences between Qizx/open and Qizx
3.1. Java API
3.2. Function fn:doc()
3.3. Function fn:collection()

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.

1. Getting Started with Qizx/open

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:

Qizx Studio

A graphic tool featuring a simple XML Query workbench with which you can write and execute XML Query scripts, and view the results.

qizx

A command-line tool which can be used to execute XML Query script files.

1.1. Writing and running queries with Qizx Studio

Qizx Studio currently provides a basic environment for editing and running XML Query queries.

Starting Qizx Studio

  • 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:

Figure A.1. Qizx Studio first launch

Qizx Studio first launch

Note

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 FileOpen XQuery 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.

    Important

    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:

    Figure A.2. Result of a query

    Result of a query

  • 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.

1.2. Running queries with the qizx command line tool

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).

2. Programming with the Qizx/open API

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.

2.1. Compiling and running the code samples

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.

2.2. Creating a work session

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();

Tuning the document cache:

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).

2.3. Compiling and executing queries

Compiling and running a XML Query script is fairly easy:

Expression expr = session.compileExpression(script);1
ItemSequence results = expr.evaluate();2        
while (results.moveToNextItem()) {3
    Item result = results.getCurrentItem();

    /*Do something with result.*/
}

1

First compile an XQuery expression using XQuerySession.compileExpression. The argument script contains a XQuery query expression as a string. If no compilation errors (CompilationException) are found, this returns an Expression object.

2

Then evaluate the expression using Expression.evaluate. If no evaluation errors (EvaluationException) are found, this returns the results of the evaluation in the form of an ItemSequence.

3

An ItemSequence allows to iterate over a sequence of Items (see About Qizx iterators). A Item is either an atomic value or an XML Node.

Example (1.xq):

(: Compute and return 2 + 3 :)
2 + 3

evaluates to an ItemSequence containing a single atomic value (5).

Example (3.xq):

(: 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 ItemSequence containing several t:title element Nodes.

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);1
            }
        }

        return expr;
    }

1

An XQuery expression can be further parametrized by the use of variables. Example (101.xq):

(: 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)]

Expression.bindVariable allows to give a variable its value, prior to evaluating the expression.

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);1
        }

        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)2
                break;
        }
        System.out.flush();
    }

1

ItemSequence.skip allows to quickly skip the specified number of Items.

2

This being done, you still need to limit the number of Items you are going to display.

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()) {1
            System.out.println(result.getString());2
            return;
        }
        Node node = result.getNode();3

        serializer.reset();
        String xmlForm = serializer.serializeToString(node);4
        System.out.println(xmlForm);
    }

1 3

Item.isNode returns true for a Node and false for an atomic value. Similarly, Item.getNode returns a Node when the Item actually is a Node and null when the Item is an atomic value.

2

Item.getString returns the string value of an Item (whether Node or atomic value). What precisely is the string value of an Item is specified in the XQuery standard.

4

The XMLSerializer.serializeToString convenience method is used to obtain the string representation of a Node.

2.3.1. Compiling and running the code of this lesson

  • 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/.

3. Differences between Qizx/open and Qizx

Table A.1. Summary of functional differences between Qizx/open and Qizx

 QizxQizx/open
Basic features of the XML Query languageyesyes
Optional features of the XML Query language: Modules, Full Axisyesyes
Persistent compressed document storageyes-
In-memory XML documentsyesyes
Indexed queriesyes-
ACID transactions, hot backupyes-
Full-text searchyesyes, but not indexed
Unlimited database sizeyes-
General XQuery extension functionsyesyes
XML Library handling extension functionsyes-
Join optimizationsyesyes
Java Bindingyesyes
Java APIyesyes (cut down)
Source code of applications, API and utilitiesyesyes
Source code of the XQuery engine-yes

3.1. Java API

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 .

3.2. Function fn:doc()

fn:doc ($path-or-URL as xs:string)
   as node()

The standard doc() function of XQuery.

Parameter $path-or-URLThis 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")

3.3. Function fn:collection()

fn:collection ($path as xs:string)
   as node()*

This is the standard collection() function of XQuery, slightly extended.

Parameter $pathThis 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 collection("/home/data1/*.xml;/home/data2/*.xml") can be expanded, while collection("/home/*/*.xml;") currently cannot be expanded (generates an error).

  • 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")