Developer's Guide

1. Using the XML-RPC API

XML-RPC (XML Remote Procedural Call) provides a simple way to call remote procedures from a wide variety of programming languages. eXist's XML-RPC API makes it easy to access eXist from other applications, CGI scripts, PHP, JSP and more. For more information on XML-RPC see www.xmlrpc.org. For the Java server, eXist uses the XML-RPC library created by Hannes Wallnoefer which recently has moved to Apache (see: http://xml.apache.org/xmlrpc). Perl examples use the RPC::XML package, which should be available at every CPAN mirror (see CPAN).

The following is a small example, which shows how to talk to eXist from Java using the Apache XML-RPC library. This example can be found in samples/org/exist/examples/xmldb/Retrieve.java.

Example: Retrieving a document from eXist

 
public class Retrieve {

protected final static String uri = 
    "http://localhost:8080/exist/xmlrpc";

protected static void usage() {
    System.out.println( "usage: org.exist.examples.xmlrpc.Retrieve " +
        "path-to-document" );
    System.exit( 0 );
}

public static void main( String args[] ) throws Exception {
    if ( args.length < 1 ) {
        usage();
    }
    XmlRpc.setEncoding("UTF-8");
    XmlRpcClient xmlrpc = new XmlRpcClient( uri );
    Hashtable options = new Hashtable();
    options.put("indent", "yes");
    options.put("encoding", "UTF-8");
    options.put("expand-xincludes", "yes");
    options.put("highlight-matches", "elements");
    
    Vector params = new Vector();
    params.addElement( args[0] ); 
    params.addElement( options );
    String xml = (String)
        xmlrpc.execute( "getDocumentAsString", params );
    System.out.println( xml );
}
}

As shown above, the execute method of XmlRpcClient expects as its parameters a method (passed as a string) to call on the server and a Vector of parameters to pass to this executed method. In this example, the method getDocumentAsString is called as the first parameter, and a Vector params. Various output properties can also be set through the hashtable argument (see the method description below). Since all parameters are passed in a Vector, they are necessarily Java objects.

XML-RPC messages (requests and responses sent between the server and client) are themselves XML documents. In some cases, these documents may use a character encoding which is in conflict with the encoding of the document we would like to receive. It is thus important to set the transport encoding to UTF-8 as shown in the above example. However, conflicts may persist depending on which client library is used. To avoid such conflicts, eXist provides alternative declarations for selected methods, which expect string parameters as byte arrays. The XML-RPC library will send them as binary data (using Base64 encoding for transport). With this approach, document encodings are preserved regardless of the character encoding used by the XML-RPC transport layer.

Note

Please note that the XML-RPC API uses int to encode booleans. This is because some clients do not correctly pass boolean parameters.

Querying is as easy using XML-RPC. The following example:

Example: Sending a Query to eXist (XML-RPC)

#!/usr/bin/perl
use RPC::XML;
use RPC::XML::Client;

$query = <<END;
for \$speech in //SPEECH[LINE &= 'tear*']
order by \$speech/SPEAKER[1]
return
    \$speech
END

$URL = "http://guest:guest\@localhost:8080/exist/xmlrpc";
print "connecting to $URL...\n";
$client = new RPC::XML::Client $URL;

# Output options
$options = RPC::XML::struct->new(
    'indent' => 'yes', 
    'encoding' => 'UTF-8',
    'highlight-matches' => 'none');

$req = RPC::XML::request->new("query", $query, 20, 1, $options);
$response = $client->send_request($req);
if($response->is_fault) {
    die "An error occurred: " . $response->string . "\n";
}
print $response->value;

You will find the source code of this example in samples/xmlrpc/search2.pl. It uses the simple query method, which executes the query and returns a document containing the specified number of results. However, the result set is not cached on the server.

The following example calls the executeQuery method, which returns a unique session id. In this case, the actual results are cached on the server and can be retrieved using the retrieve method.

Example: Another Query Examplet (XML-RPC)

use RPC::XML;
#!/usr/bin/perl

use RPC::XML;
use RPC::XML::Client;

# Execute an XQuery through XML-RPC. The query is passed
# to the "executeQuery" method, which returns a handle to
# the created result set. The handle can then be used to
# retrieve results.

$query = <<END;
for \$speech in //SPEECH[LINE &= 'corrupt*']
order by \$speech/SPEAKER[1]
return
    \$speech
END

$URL = "http://guest:guest\@localhost:8080/exist/xmlrpc";
print "connecting to $URL...\n";
$client = new RPC::XML::Client $URL;

# Execute the query. The method call returns a handle
# to the created result set.
$req = RPC::XML::request->new("executeQuery", 
    RPC::XML::base64->new($query), 
	"UTF-8");
$resp = process($req);
$result_id = $resp->value;

# Get the number of hits in the result set
$req = RPC::XML::request->new("getHits", $result_id);
$resp = process($req);
$hits = $resp->value;
print "Found $hits hits.\n";

# Output options
$options = RPC::XML::struct->new(
    'indent' => 'no', 
    'encoding' => 'UTF-8');
# Retrieve query results 1 to 10
for($i = 1; $i < 10 && $i < $hits; $i++) {
    $req = RPC::XML::request->new("retrieve", $result_id, $i, $options);
    $resp = process($req);
    print $resp->value . "\n";
}

# Send the request and check for errors
sub process {
    my($request) = @_;
    $response = $client->send_request($request);
    if($response->is_fault) {
        die "An error occurred: " . $response->string . "\n";
    }
    return $response;
}

2. XML-RPC: Available Methods

This section gives you an overview of the methods implemented by the eXist XML-RPC server. Only the most common methods are presented here. For a complete list see the Java interface RpcAPI.java. Note that the method signatures are presented below using Java data types. Also note that some methods like getDocument() and retrieve() accept a struct to specify optional output properties.

In general, the following optional fields for methods are supported:

indent

Returns indented pretty-print XML. [yes | no]

encoding

Specifies the character encoding used for the output. If the method returns a string, only the XML declaration will be modified accordingly.

omit-xml-declaration

Add XML declaration to the head of the document. [yes | no]

expand-xincludes

Expand XInclude elements. [yes | no]

process-xsl-pi

Specifying "yes": XSL processing instructions in the document will be processed and the corresponding stylesheet applied to the output. [yes | no]

highlight-matches

Database adds special tags to highlight the strings in the text that have triggered a fulltext match. Set to "elements" to highlight matches in element values, "attributes" for attribute values or "both" for both elements and attributes.

stylesheet

Use this parameter to specify an XSL stylesheet which should be applied to the output. If the parameter contains a relative path, the stylesheet will be loaded from the database.

stylesheet-param.key1 ... stylesheet-param.key2

If a stylesheet has been specified with stylesheet, you can also pass it parameters. Stylesheet parameters are recognized if they start with the prefix stylesheet-param., followed by the name of the parameter. The leading "stylesheet-param." string will be removed before the parameter is passed to the stylesheet.

2.1. Retrieving documents

2.2. Storing Documents

2.3. Creating a Collection

2.4. Removing Documents or Collections

2.5. Querying

2.6. Retrieving Information on Collections and Documents

2.7. XUpdate

2.8. Managing Users and Permissions

2.9. Access to the Index Contents

The following methods provide access to eXist's internal index structure.

2.10. Other Methods

September 2009
Wolfgang M. Meier
wolfgang at exist-db.org