function counter(initValue)
{
this.value = initValue ;
}
function nextCount(ctr)
{
return ctr.value++ ;
}
function resetCount(ctr,value)
{
ctr.value = value ;
return "" ;
}
function makeCount(initValue)
{
return new counter(initValue) ;
}
Count:
Count:
Count:
Count:
Count:
qqqqq
function Matcher(pattern)
{
this.re = new RegExp(pattern) ;
this.re.compile(pattern) ;
this.result= "" ;
this.left="" ;
this.right="" ;
}
function match(matcher, input)
{
matcher.result = matcher.re.exec(input) ;
matcher.left = RegExp.leftContext ;
matcher.right = RegExp.rightContext ;
return matcher.result[0] ;
}
function leftContext(matcher)
{
return matcher.left ;
}
function rightContext(matcher)
{
return matcher.right ;
}
function getParenMatch(matcher, which)
{
return matcher.result[which] ;
}
function makeRegExp(pattern)
{
return new Matcher(pattern) ;
}
Match:
Left:
Right:
Month:
Day:
Year:
This code results in:
Match: 04/11/1855
Left: I was born on
Right: in London.
Month: 04
Day: 11
Year: 1855
qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
For example: SAXON XSLT
This will invoke the static method java.lang.Math.sqrt(), applying it to the value of the variable $arg, and copying the value of the square root of $arg to the result tree.
from jclark.com XT documentation:
'The following stylesheet prints the date and time. This example is copied from the documentation of the xt product, and it works unchanged with SAXON, because SAXON does not care what the namespace URI for extension functions is, so long as it ends with the class name. (Extension functions are likely to be compatible between SAXON and xt provided they only use the data types string, number, and boolean).'
Note that Saxon's tree structure conforms to the DOM Core Level 2 interface. However, it is read-only: any attempt to modify the tree causes an exception. Saxon's trees can only be built using the Saxon subclasses of the com.icl.saxon.tree.Builder class, and they cannot be modified in situ.
Writing Java node handlers
A Java node handler can be used to process any node, in place of an XSL template. The handler is nominated by using a saxon:handler element with a handler attribute that names the node handler class. The handler itself is an implementation of com.icl.saxon.NodeHandler or one of its subclasses (the most usual being com.icl.saxon.ElementHandler). The saxon:handler element must be a top-level element, and must be empty. It takes the same attributes as xsl:template (match, mode, name, and priority) and is considered along with xsl:template elements to decide which template to execute when xsl:call-template or xsl:apply-templates is used.
Java node handlers have full access to the source document and the current processing context (for example, the values of parameters). The may also trigger processing of other nodes in the document by calling applyTemplates(): this works just like xsl:apply-templates, and the selected nodes may be processed either by XSL templates or by further Java node handlers.
A Java node handler may also be registered with a name, and may thus be invoked using xsl:call-template. There is no direct mechanism for a Java node handler to call a named XSLT template, but the effect can be achieved by using a mode that identifies the called template uniquely.
Writing input filters
SAXON takes its input from a SAX2 Parser reading from an InputSource. A very useful technique is to interpose a filter between the parser and SAXON. The filter will typically be an instance of the SAX2 XMLFilter class.
See the TrAX examples for hints on using a Saxon Transformer as part of a chain of SAX Filters.
(( an error-correcting parser can be built by you coding the SAX eventHandlers adequately ))
Note that SAXON relies on the application to supply a well-balanced sequence of SAX events; it doesn't need to be well-formed (the root node can have any number of element or text children), but if it isn't well-balanced, the consequences are unpredictable.
Writing output filters
The output of a SAXON stylesheet can be directed to a user-defined output filter. This filter can be defined either as a standard SAX1 DocumentHandler, a SAX2 ContentHandler, or as a subclass of the SAXON class com.icl.saxon.output.Emitter. The advantage of using an Emitter is that more information is available from the stylesheet, for example the attributes of the xsl:output element.
When a ContentHandler is used, Saxon will by default always supply a stream of events corresponding to a well-formed document. (The XSLT specification also allows the output to be an external general parsed entity.) If the result tree is not well-formed, Saxon will notify the content handler of the fact by sending a processing instruction with the name "saxon:warning" and the text "Output suppressed because it is not well-formed". If the content handler is happy to accept output that is not well-formed, it can respond to this processing instruction by throwing a SAXException whose message text is "continue"; in this case subsequent events will be notified whether or not they are well-formed.
The best way to see how to implement an extension element is by looking at the example, for SQL extension elements, provided in package com.icl.saxon.sql, and at the sample stylesheet books.sqlxsl which uses these extension elements.
Saxon
parse(string)
This function takes a single argument, a string containing the source text of a well-formed XML document. It returns the document node (root node) that results from parsing this text. It throws an error if the text is not well-formed XML. Applications should not rely on the identity of the returned document node (at present, if the function is called twice with the same arguments, it returns a new document node each time, but this may change in future).
This function is useful where one XML document is embedded inside another using CDATA, or as an alternative way of passing an XML document as a parameter to a stylesheet.
eval(stored-expression)
This returns the result of evaluating the supplied stored expression. A stored expression may be obtained as the result of calling the saxon:expression() function.
The stored expression is evaluated in the current context, that is, the context node is the current node, and the context position and context size are the same as the result of calling position() or last() respectively.
Example: saxon:eval(saxon:expression(concat(2, $op, 2)))
evaluate(string)
The supplied string must contain an XPath expression. The result of the function is the result of evaluating the XPath expression. This is useful where an expression needs to be constructed at run-time or passed to the stylesheet as a parameter, for example where the sort key is determined dynamically. The context for the expression (e.g. which variables and namespaces are available) is exactly the same as if the expression were written explicitly at this point in the stylesheet. The function saxon:evaluate(string) is shorthand for saxon:eval(saxon:expression(string)).
expression(string)
The supplied string must contain an XPath expression. The result of the function is a stored expression, which may be supplied as an argument to other extension functions such as saxon:eval(), saxon:sum() and saxon:distinct(). The result of the expression will usually depend on the current node. The expression may contain references to variables that are in scope at the point where saxon:expression() is called: these variables will be replaced in the stored expression with the values they take at the time saxon:expression() is called, not the values of the variables at the time the stored expression is evaluated. Similarly, if the expression contains namespace prefixes, these are interpreted in terms of the namespace declarations in scope at the point where the saxon:expression() function is called, not those in scope where the stored expression is evaluated.