P6R's XSLT 2.0 implementation uses the following P6R's components: XPath 2.0 (P6R::p6IXpathExpression), DOMXML (P6R::p6DOMXML), SAX2 (P6R::p6ISAX2XMLReader), and JSON (P6R::p6IJSONReader). This XSLT processor can also use XML, JSON, or JsonML as its source document (the XSLT templates are still in XML).
P6R's XPath 2.0 implementation also allows an application to extend the XSLT Processor's behavior via the XPath interface P6R::p6IXpathVariables (which allows an application to define their own functions and variables that are recognized in an XPath expression). The calling application creates its own implementation of the P6IXPathVariables interface and then calls the P6R::p6IXSLT::setExternalFunctions() method. This is significant that now an application can define its own global variables which can change each time they are referenced. These external variables can be used for many purposes including with Compiled templates (see below).
Please note that this documentation does not provide details on the XSLT, XPath, XML, JSON, or JsonML languages (references are included for that). This documentation describes how to use the P6R components that implement the standards as well as to point out unique features of our products.
1) M.Kay, "XSLT 2.0 Programmer's Reference", 3rd Edition, 2004, Wiley Publishing Inc., ISBN: 0-7645-6909-0.
2) M.Kay, XPath 2.0, Programmer's Reference, Wiley Publishing Inc, 2004, ISBN 0-7645-6910-4.
3) N.Bradley, "The XSL Companion", 2000, Addison-Wesley, ISBN: 0-201-67487-4.
4) http://www.w3.org/TR/xslt20/, the XSLT W3C specification
5) http://www.json.org, the JSON language definition
6) http://www.jsonml.org, the JsonML language defintion
7) http://saxon.sourceforge.net/saxon7.9/extensions.html, Saxon Extensions
XSLT and XPath for JSON - https://www.p6r.com/articles/2008/05/06/xslt-and-xpath-for-json/
<xsl:output method=’json’/> - https://www.p6r.com/articles/2008/11/02/xsloutput-methodjson/
Any JSON and JsonML can be loaded into P6R's DOM tree. However, there are limitations using XPath and outputing such a DOM tree as XML. JSON and JsonML allow a larger character set for use in object names than does XML and XPath. XPath has several characters that might collide with a JSON object name. For example, XPath uses characters such as '/' (used as a step in a path) and '@' (used to access a node's attribute) as special symbols that cannot appear in an XML node's name.
When outputing a JSON originated DOM tree, any JSON object name (which becomes a DOM node name) that starts with a number (e.g., "{ "9top" : "some object value" } ) will get translated on XML output replacing the number with the default character "_". The above JSON example would end up being the following XML: "<?XML ..><top>some object value</_top>". In addition, any other non-XML characters that appear in the JSON object name will also be replaced with the default "" character. This is done so that the outputed XML is valid XML. Note, that this translation only happens when outputing the DOM tree as XML. Outputing the DOM tree as JSON or JsonML perserves the orgininal object names.
The implementation of <xsl:strip-space> and <xsl:preserve-space> is done while the DOM tree is being built from streaming XML input. Thus these functions do not incur any significant performance penality. The white space stripping is done by calling the methods P6R::p6IDOMXML::stripSpace() and P6R::p6IDOMXML::preserveSpace() from our XML DOM parser.
Our XSLT processor allows the caller to compile a template once and use it over and over again to generate pages. See Section "Compiled Templates and Multiple Threads" below.
A detailed document on this topic has been published at the following URL: https://www.p6r.com/articles/2008/09/03/compiled-tempates-for-xslt-20/
The following XSLT functions have not yet been implemented: format-number() (try using the P6R:format-number() XPath extension function which is specified in the XPath documentation), unparsed-entity-public-id(), and unparsed-entity-uri(). The function "unparsed-text()" is implemented but it only supports "UTF-8" and "iso-8859-1" encodings.
The following elements have not yet been implemented in P6R's XSLT 2.0 implementation: 'decimal-format', 'document', 'import-schema', 'namespace-alias', and 'number' (see our XSLT extensions for an alternative to xsl:number). These elements are simply ignored if encountered by the P6R XSLT 2.0 processor.
In addition, the sequence constructor part of a 'perform-sort' element has not yet been implemented. So the "select=" attribute must be defined for the 'perform-sort' element to work properly. Also, "Built-in Template Rules" are not yet implemented (M.Kay, p.70).
In addition, the current implementation does not yet have a full URI resolver so only relative URIs to files on disk is supported. A full URI resolver will be included in the near future.
In the xsl:output element the following methods are supported: { xml, html, xhtml, text, json }. Also the following QNames are supported for the xsl:output element:
As a simple example:
These added elements require the use of the Saxon namespace: http://saxon.sf.net
The following is the list of Saxon supported element extensions: assign.
From reference 7: "The saxon:assign element is used to change the value of a local or global variable that has previously been declared using xsl:variable (or xsl:param).
The variable or parameter must be marked as assignable by including the extra attribute saxon:assignable="yes" [not required in the P6R XSLT processor].
As with xsl:variable, the name of the variable is given in the mandatory name attribute, and the new value may be given either by an expression in the select attribute, or by expanding the content of the xsl:assign element."
Note that in our implementation of this extension the 'saxon:assignable="yes"' attribute is NOT required and is in fact ignored.
P6R has restricted support for Attribute Value Templates [1, p.116] because of our compiled templates feature. Many XSLT elements allow some of there attributes to be passed in as part of the "enviroment" BEFORE template compilation. This way an XSLT element can be parameterized. For example, the sort element allows many of its attributes (e.g., order = { ascending | descending }, and collation = { uri }) to be determined at compile time via parameters to the compile/transform call.
The problem with this type of value expansion is that it can only happen once with compiled templates. Using the XSLT sort element as an example, the same template would have to be compiled with both values for the "order" attribute just in case that attribute could be set by a user at a Web UI. Instead of using these "hard coded" values we allow the calling application to use the XSLT processor's ability to define external, global variables. These application controlled variables can change at any time and can be defined differently for each instance of a running XSLT processor.
Again using the sort element for an example, we would change all appearences of the "order" attribute to reference a global variable that is NOT defined in the XSLT style sheet. When the XSLT processor runs into such a reference it calls the P6R::P6IXPathVariables::lookupVariable() method of an object that is defined by the application. This object makes it self known by calling the XSLT processors P6R::p6IXSLT::setExternalFunctions() method to register.
Once the P6R::P6IXPathVariables object is registered, the application can dynamically return the value for the "order" attribute as it sees fit based on whatever external input it can access (e.g., a file, a socket). The XSLT sort element also allows the caller to set a collation string via an attribute value template. Just as we did with the order attribute, the calling application can use different collations based on if it is running on a Windows or Unix operating system or if some web user has selected a different language to view an XSLT generated page.
The P6R XSLT processor does support references to variables inside non-XSLT elements (e.g., an attribute of an HTML element making reference to an XSLT variable: <A href='{$lv4}'>Hi There</A> , here a URL is defined by the XSLT variable "{$lv4}".
A QName is essentially the result of resolving an XML prefix to its URI value. For example, given the element: "<html:h2>", where the "html" name space has the associated name space definition: xmlns:html='http://www.w3.org/1999/xhtml', the QName must represent that URI and the 'local' part of the name which is 'h2'. There is no standard on how this is done so we have the following algorthm:
So for our example above its QName would be: 'http-&&www.w3.org&1999&xhtml&p-h2'. Anything that has a namespace prefix is translated into a QName by the XSLT compiler. In the Section above, P6R's XSLT Element Extensions, we defined our own version of the 'number' XSLT element, which requires the use of the 'http://www.p6r.com/XSLT/extensions' namespace URI. Every time the XSLT compiler sees an element defined as '<P6R:number>' with the matching xmlns:P6R='http://www.p6r.com/XSLT/extensions' definition, it will translate the reference into the element: 'http-&&www.p6r.com&XSLT&extensions&p-number' which is the string that the XSLT run-time processor is expecting.
This translation is done because the actual prefix used (e.g., 'P6R', 'html') is meaningless. Equality comparison must be done by matching URIs and the local part of the name. Please refer to any of the references listed in the Section, XSLT References, above.
All 'collation' and 'lang' attributes of XSLT elements (e.g., sort, key, for-each-group) can be full XPath expressions in P6R's XSLT processor. This allows then to obtain values from source documents as well as external functions (see Section "Attribute Value Templates" above).