Tamino XML Server Version 9.7
 —  Advanced Concepts  —

More Examples

In this section we provide a few more examples of server functions. We have implemented:

We call this server extension module xqx and name the package accordingly tamino.sxs.xqx. The complete source code, including the file Install.xml and the Javadoc HTML file, is contained in the directory sxsjxqx in the documentation set.


Top of page

concat

Concatenates strings.

Syntax

public String concat (String op1, String op2)
public String concat3 (String op1, String op2, String op3)
public String concat4 (String op1, String op2, String op3, String op4)

Top of page

Description

The original XPath concat() string function allows any number of arguments (at least 2). We have implemented the functions concat, concat3, and concat4 to cover cases with two, three, and four arguments. The implementation could hardly be simpler:

public String concat (String op1, String op2) {
  return op1+op2;
}
public String concat3 (String op1, String op2, String op3) {
  StringBuffer sb = new StringBuffer(op1);
  sb.append(op2);
  sb.append(op3);
  return sb.toString();
}
public String concat4 (String op1, String op2, 
                       String op3, String op4) {
  StringBuffer sb = new StringBuffer(op1);
  sb.append(op2);
  sb.append(op3);
  sb.append(op4);  
  return sb.toString();
}

Top of page

Examples

xqx.concat(name/last, name/first)

constructs an ID from last name and first name.

xqx.concat3(birthDate,"T","04:30:00")

appends a time to a date.


Top of page

contains

True if op1 contains op2.

Syntax

public boolean contains (String op1, String op2)

Top of page

Description

The string function contains() is a bit more demanding:

public boolean contains (String op1, String op2) {
  return (op1.indexOf(op2) >= 0);
}

Top of page

Examples

xqx.contains(title,"Moon in June")

is true for all titles containing "Moon in June". In contrast to the X-Query contains-operator (~=), this function is case sensitive.


Top of page

substringBefore

Returns substring before op2.

Syntax

public String substringBefore (String op1, String op2)

Top of page

Description

The original XPath name is substring-before().

public String substringBefore (String op1, String op2) {
  int i = op1.indexOf(op2);
  if (i > 0) return op1.substring(0,i);
  return "";
}

Top of page

Examples

xqx.substringBefore(performedAt/time,"T")

returns the date part of dateTime element performedAt/time.

 
          
        

Top of page

substringAfter

Returns substring after op2.

Syntax

public String substringAfter (String op1, String op2)

Top of page

Description

The original XPath name is substring-after().

public String substringAfter (String op1, String op2) {
  int i = op1.indexOf(op2);
  if (i >= 0) {
    int b = op2.length()+i;
    if (b < op1.length()) return op1.substring(b);
  }
  return "";
}

Top of page

Examples

xqx.substringAfter(performedAt/time,"T")

returns the time part of dateTime element performedAt/time.


Top of page

substring

Returns substring from position p with length l.

Syntax

public String substring (String s, int p, int l)

Top of page

Description

Two substring functions are provided in XPath:

Because Tamino server extensions do not support method overloading, we implement only the three-argument form. The length -1 indicates the two-argument version (substring up to end of string).

public String substring (String s, int p, int l) {
  p--;          // Java counts from 0, Xpath from 1
  if (l < 0) return s.substring(p);
  return s.substring(p,p+l);
}

Top of page

Examples

xqx.substring(1999-05-01,6,2)

returns the month ("05").

xqx.substring(1999-05-01,6,-1)

returns the month and the day ("05-01").


Top of page

trim

Removes white space from beginning and end.

Syntax

public String trim (String s)

Top of page

Description

Here we implement a function that is not available in XPath but works similarly to the XPath string function normalize-space(). However, trim() only removes leading and trailing white space from a string, leaving white space in the interior of the string intact. Again, the implementation is trivial:

public String trim (String s) {
  return s.trim();
}

Top of page

Examples

If a document instance of document type style contains an element:

<name>
    swing
</name>

then the simple path expression:

style/name

returns "swing" with leading and trailing carriage-return characters and blanks. In many cases this is unwanted, for example if we want to use the string as a search string or concatenate it with other strings.

xqx.trim(style/name)

removes these unwanted white space characters.


Top of page

normalizeSpace

Normalizes white space.

Syntax

public String normalizeSpace (String s)

Top of page

Description

The full implementation of normalize-space() requires a bit more coding:

public String normalizeSpace (String s) {
  StringBuffer sb = new StringBuffer(s.length());
  boolean whiteSpace = true;
  for (int i=0; i < s.length(); i++) {
    char c = s.charAt(i);
    if ((c==' ')||(c==13)||(c==10)||(c==9)) {
      if (!whiteSpace) {
        whiteSpace = true;
        sb.append(' ');
      }
    } else {
      sb.append(c);
      whiteSpace = false;
    }
  }
  if (whiteSpace) {
    sb.deleteCharAt(sb.length()-1);
  }
  return sb.toString();
}

Top of page

Examples

If a document instance of document type album contains an element:

<title>
    Open Up 
    (Whatcha gonna do for the rest of your     life?)
</title>

then the simple path expression:

album/title

returns the title with all carriage-return, linefeed, tab, and blank characters.

xqx.normalizeSpace(album/title)

normalizes this string to:

    Open Up (Whatcha gonna do for the rest of your life?)

Top of page

stringLength

Returns length of string.

Syntax

public int stringLength (String s)

Top of page

Description

The original XPath name is string-length(). The implementation is trivial:

public int stringLength (String s) {
  return s.length();
}

Top of page

Examples

xqx.stringLength(name/last)

returns the length of the element name/last including white space characters.

jazzMusician[xqx.stringLength(./name/last)=9]

returns all jazz musicians whose last name is 9 characters long.


Top of page

qdoc

Fetches document specified by path.

Syntax

public String qdoc (String qpath)

Top of page

Description

Finally, here is a function that is similar to the document() function in XPath, but constrains itself to documents stored in the same database. This allows us to implement the retrieval of the document via a Tamino callback function, instead of retrieving the document via an HTTP request.

The function takes one argument, namely an X-Query expression that identifies the document (or document part). This expression must include the collection name. Before returning a result, it strips off all of Tamino's packaging for query results and returns the data as a vanilla XML node (or node list).

public String qdoc (String qpath) 
                   throws java.lang.Exception {
  // split operand into collection and relative path
  int p = qpath.indexOf("/", 0);
  if (p<0) 
   throw(new Exception("Proper syntax is collection/path"));
  StringBuffer response = new StringBuffer(1024);
  // do query to Tamino via SXS callback
  int ret = SxsXMLXql (qpath.substring(0,p), 
                       qpath.substring(p+1), response);
  if (ret != 0)
    // Error handling as shown in section Derived elements
    // ....
  }
  // Create document string
  String  docstr = response.toString();
  // We have to isolate the returned node(s)
  int t = docstr.indexOf("<xql:result>", 0)+12;
  if (t >= 12) {
    int e = docstr.indexOf("</xql:result>", t);
    return docstr.substring(t,e);
  }
  return "";
}

Top of page

Examples

Since qdoc() – in contrast to document() – does not require the full specification of a URL and removes the Tamino response wrapping, queries using qdoc() are significantly simpler. The following query finds all collaborations in which jazz musicians whose last name is "Parker" participated:

collaboration[jazzMusician/@ID=xqx.qdoc(
             "encyclopedia/jazzMusician[name/last='Parker']"
             )/@ID]

The next query finds all jazz musician documents taking part in such collaborations. We see that qdoc() can be nested. Note that we have to use the &quot; notation for the innermost level of string demarcations.

jazzMusician[@ID = xqx.qdoc(
  "encyclopedia/collaboration[jazzMusician/@ID=xqx.qdoc(
   'encyclopedia/jazzMusician[name/last=&quot;Parker&quot;]'
  )/@ID]")/jazzMusician/@ID]

Similarly, the following query returns all album documents that are the result of such a collaboration:

album[@albumNo = xqx.qdoc(
  "encyclopedia/collaboration[jazzMusician/@ID=xqx.qdoc(
   'encyclopedia/jazzMusician[name/last=&quot;Parker&quot;]'
  )/@ID]")/result/@albumNo]

Top of page