Difference between revisions of "XSLT Module"

From BaseX Documentation
Jump to navigation Jump to search
m (Text replacement - "syntaxhighlight" to "pre")
 
(91 intermediate revisions by 2 users not shown)
Line 1: Line 1:
This module contains [[Querying#Functions|XQuery functions]] and variables to perform XSLT transformations. All functions are preceded by the <code>xslt:</code> prefix, which is linked to the <code>http://www.basex.org/modules/xslt</code> namespace.
+
This [[Module Library|XQuery Module]] contains functions and variables to perform XSL transformations.
  
By default, this module uses the internal XSLT 1.0 implementation of Java to transform documents. XSLT 2.0 is used instead if Version 9.x of the [http://www.saxonica.com/ Saxon XSLT Processor] (<code>saxon9he.jar</code>, <code>saxon9pe.jar</code>, <code>saxon9ee.jar</code>) is found in the classpath.
+
By default, this module uses Java’s XSLT 1.0 Xalan implementation to transform documents. XSLT 3.0 is used if the [https://www.saxonica.com/ Saxon XSLT Processor] is found in the class path (e.g. by placing the library files in the [[Startup#Full Distributions|{{Code|lib/custom}} directory]]). A specific transformer can be specified by assigning a classpath to the system property {{Code|javax.xml.transform.TransformerFactory}} with the [https://docs.oracle.com/en/java/javase/11/tools/java.html -D flag] on the command line, or directly in Java:
  
A [[XSLT Functions (Snapshot)|preview page]] describes the features of the [http://files.basex.org/releases/latest/ latest stable snapshot].
+
<pre lang="java">
 +
System.setProperty(
 +
  "javax.xml.transform.TransformerFactory",
 +
  "org.custom.xslt.TransformerFactoryImpl");
  
==$xslt:processor==
+
Context ctx = new Context();
{|
+
String result = new XQuery("xslt:transform('...', '...')").execute(ctx);
|-
+
...
| valign='top' width='90' | '''Signatures'''
+
ctx.close();
|<code><b>$xslt:processor</b> as xs:string</code><br />
+
</pre>
|-
+
 
| valign='top' | '''Summary'''
+
=Conventions=
|This variable contains the name of the applied XSLT processor (currently: <code>Java</code> or <code>Saxon</code>).<br />
+
 
 +
All functions and errors in this module are assigned to the <code><nowiki>http://basex.org/modules/xslt</nowiki></code> namespace, which is statically bound to the {{Code|xslt}} prefix.<br/>
 +
 
 +
=Functions=
 +
 
 +
==xslt:processor==
 +
 
 +
{| width='100%'
 +
|- valign="top"
 +
| width='120' | '''Signature'''
 +
|{{Code|'''xslt:processor'''() as xs:string}}<br/>
 +
|- valign="top"
 +
| '''Summary'''
 +
|Returns the name of the applied XSLT processor ("Java", "Saxon EE", "Saxon PE", "Saxon HE"). If a system property was assigned that points to an existing implementation other than Saxon, the classpath is returned instead.<br/>
 
|}
 
|}
  
==$xslt:version==
+
==xslt:version==
{|
+
 
|-
+
{| width='100%'
| valign='top' width='90' | '''Signatures'''
+
|- valign="top"
|<code><b>$xslt:version</b> as xs:string</code><br />
+
| width='120' | '''Signature'''
|-
+
|{{Code|'''xslt:version'''() as xs:string}}<br/>
| valign='top' | '''Summary'''
+
|- valign="top"
|This variable contains the supported XSLT version (currently: <code>1.0</code> or <code>2.0</code>).<br />
+
| '''Summary'''
 +
|Returns the supported XSLT version ("1.0", "3.0"). An empty string is returned if a classpath in the system property points to an existing implementation other than Saxon.<br/>
 
|}
 
|}
  
 
==xslt:transform==
 
==xslt:transform==
{|
+
 
|-
+
{| width='100%'
| valign='top' width='90' | '''Signatures'''
+
|- valign="top"
|<code><b>xslt:transform</b>($input as item(), $stylesheet as item()) as node()</code><br /><code><b>xslt:transform</b>($input as item(), $stylesheet as item(), $params as item()) as node()</code>
+
| width='120' | '''Signature'''
|-
+
|<pre>xslt:transform(
| valign='top' | '''Summary'''
+
  $input       as item(),
|Transforms the document specified by <code>$input</code>, using the XSLT template specified by <code>$stylesheet</code>, and returns the result as <code>node()</code> instance. If Saxon is found in the Java classpath, <code>XSLT 2.0</code> is applied; otherwise, Java’s internal <code>XSLT 1.0</code> Xalan implementation is used. <code>$input</code> and <code>$stylesheet</code> can be specified as<br />
+
  $stylesheet as item(),
* <code>xs:string</code>, containing the path to the document,
+
  $arguments  as map(*)?  := map { },
* <code>xs:string</code>, containing the document in its string representation, or
+
  $options    as map(*)?  := map { }
* <code>node()</code>, containing the actual document.
+
) as node()</pre>
The <code>$params</code> argument can be used to bind variables to a stylesheet. It can be specified as
+
|- valign="top"
* <code>element(xslt:parameters)</code>: <code>&lt;xslt:parameters/&gt;</code> must be used as root element, and the parameters are specified as child nodes, with the element name representing the key and the text node representing the value:<br /><code>&lt;xslt:parameters&gt;<br/>&nbsp;&nbsp;&lt;xslt:key1&gt;value1&lt;/xslt:key1&gt;<br/>&nbsp;&nbsp;...<br/>&lt;/xslt:parameters&gt;</code>
+
| '''Summary'''
* [[Map_Functions|map structure]]: all parameters can be directly represented as key/value pairs:<br /><code>map { "key1" := "value1", ... </code>}<br/>This variant is more compact, and it facilitates the binding of arbitrary data types. Note that only strings are supported when using Saxon (XSLT 2.0). Next, the map structures are not part of the XQuery language yet, as the standardization is still in progress.
+
|Transforms the document specified by {{Code|$input}}, using the XSLT template specified by {{Code|$stylesheet}}, and returns the result as node. {{Code|$input}} and {{Code|$stylesheet}} can be specified as<br/>
|-
+
* {{Code|xs:string}}, containing the stylesheet URI,
| valign='top' | '''Errors'''
+
* {{Code|xs:string}}, containing the document in its string representation, or
|<b>[[XQuery Errors#BaseX Errors|BASX0011]]</b> is raised if the specified parameter is unknown.
+
* {{Code|node()}}, containing the document itself.
 +
[[Catalog Resolver|XML Catalog files]] will be considered when resolving URIs. Variables can be bound to a stylesheet via {{Code|$arguments}} (only strings are supported when using XSLT 3.0 and Saxon). The following {{Code|$options}} are available:
 +
* {{Code|cache}}: cache XSLT transformer (speeds up repeated transformations, but increases memory consumption)
 +
|- valign="top"
 +
| '''Error'''
 +
|{{Error|error|#Errors}} an error occurred during the transformation process.
 
|}
 
|}
  
==Examples==
+
==xslt:transform-text==
  
'''Example 1: Basic XSL transformation with dummy document and without parameters'''
+
{| width='100%'
 +
|- valign="top"
 +
| width='120' | '''Signature'''
 +
|<pre>xslt:transform-text(
 +
  $input      as item(),
 +
  $stylesheet  as item(),
 +
  $arguments  as map(*)?  := map { },
 +
  $options    as map(*)?  := map { }
 +
) as xs:string</pre>
 +
|- valign="top"
 +
| '''Summary'''
 +
|Transforms the document specified by {{Code|$input}}, using the XSLT template specified by {{Code|$stylesheet}}, and returns the result as string. The semantics of {{Code|$params}} and {{Code|$options}} is the same as for {{Function||xslt:transform}}.<br/>
 +
|- valign="top"
 +
| '''Error'''
 +
|{{Error|error|#Errors}} an error occurred during the transformation process.
 +
|}
  
'''Query:'''
+
==xslt:transform-report==
<pre class="brush:xquery">
 
xslt:transform(<dummy/>, 'basic.xslt')
 
</pre>
 
  
'''basic.xslt'''
+
{| width='100%'
<pre class="brush:xquery">
+
|- valign="top"
<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
+
| width='120' | '''Signature'''
  <xsl:template match="/">
+
|<pre>xslt:transform-report(
    <result/>
+
  $input      as item(),
  </xsl:template>
+
  $stylesheet  as item(),
</xsl:stylesheet>
+
  $arguments  as map(*)?  := map { },
</pre>
+
  $options    as map(*)?  := map { }
 +
) as xs:string</pre>
 +
|- valign="top"
 +
| '''Summary'''
 +
|Transforms the document specified by {{Code|$input}}, using the XSLT template specified by {{Code|$stylesheet}}, and returns a map with the following keys:
 +
* {{Code|result}}: The transformation result: One or more document nodes, or (if the result cannot be converted to XML) an item of type {{Code|xs:untypedAtomic}}.
 +
* {{Code|messages}}: Informational output generated by {{Code|xsl:message}} elements: A sequence of arrays. The arrays consist of XML elements, or (for those messages that cannot be converted to XML) items of type {{Code|xs:untypedAtomic}}.
 +
The semantics of {{Code|$params}} and {{Code|$options}} is the same as for {{Function||xslt:transform}}.<br/>For the moment, messages can only be returned with recent versions of Saxon.
 +
* {{Code|error}} (optional): An error string, which would be raised as an error by the other functions of this module.
 +
|}
  
'''Result:'''
+
==Examples==
<pre class="brush:xml"><result/></pre>
 
  
'''Example 2: XSLT transformation of an input document'''
+
'''Example 1: XSL transformation, with XML and XSL supplied as nodes'''
  
 
'''Query:'''
 
'''Query:'''
<pre class="brush:xquery">
+
<pre lang='xquery'>
 +
(: Outputs the result as html. :)
 +
declare option output:method 'html';
 +
 
 
let $in :=
 
let $in :=
 
   <books>
 
   <books>
 
     <book>
 
     <book>
       <title>XSLT Programmer´s Reference</title>  
+
       <title>XSLT Programmer’s Reference</title>  
 
       <author>Michael H. Kay</author>  
 
       <author>Michael H. Kay</author>  
 
     </book>
 
     </book>
Line 83: Line 128:
 
   </books>
 
   </books>
 
let $style :=
 
let $style :=
   <html xsl:version='2.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns='http://www.w3.org/1999/xhtml'>
+
   <xsl:stylesheet version='3.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
     <body>
+
  <xsl:output method='xml'/>
      <h1>Books</h1>
+
     <xsl:template match="/">
      <ul>
+
<html>
        <xsl:for-each select='books/book'>
+
  <body>
        <li>
+
    <div>
          <b><xsl:apply-templates select='title'/></b>: <xsl:value-of select='string-join(author, ", ")'/>
+
      <xsl:for-each select='books/book'>
        </li>
+
      • <b><xsl:apply-templates select='title'/></b>: <xsl:value-of select='author'/><br/>
        </xsl:for-each>
+
      </xsl:for-each>
      </ul>
+
    </div>
     </body>
+
  </body>
   </html>
+
</html>
return xslt:transform($in, $style)
+
     </xsl:template>
</pre>
+
   </xsl:stylesheet>
 +
 
 +
return xslt:transform($in, $style)</pre>
 
'''Result:'''
 
'''Result:'''
<pre class="brush:xml">
+
<pre lang="xml">
<html xmlns="http://www.w3.org/1999/xhtml">
+
<html>
 
   <body>
 
   <body>
     <h1>Books</h1>
+
     <div>
    <ul>
+
       <b>XSLT Programmer’s Reference</b>: Michael H. Kay<br>
       <li><b>XSLT Programmer´s Reference</b>: Michael H. Kay</li>
+
       <b>XSLT</b>: Doug Tidwell<br>
       <li><b>XSLT</b>: Doug Tidwell, Simon St. Laurent, Robert Romano</li>
+
     </div>
     </ul>
 
 
   </body>
 
   </body>
</html></pre>
+
</html>
 +
</pre>
 +
 
 +
'''Example 2: Textual XSL transformation'''
 +
 
 +
'''Query:'''
 +
<pre lang='xquery'>
 +
xslt:transform-text(<dummy/>, 'basic.xslt')
 +
</pre>
 +
 
 +
'''basic.xslt'''
 +
<pre lang="xml">
 +
<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
 +
  <xsl:template match="/">123</xsl:template>
 +
</xsl:stylesheet>
 +
</pre>
 +
 
 +
'''Result:'''
 +
<pre lang="xml">123</pre>
  
'''Example 3: Assigning a variable to an XSLT stylesheet'''
+
'''Example 3: XSL transformation with variable assignment'''
  
 
'''Query:'''
 
'''Query:'''
<pre class="brush:xquery">
+
<pre lang='xquery'>
 
let $in := <dummy/>
 
let $in := <dummy/>
 
let $style := doc('variable.xsl')
 
let $style := doc('variable.xsl')
return (
+
return xslt:transform($in, $style, map { "v": 1 })
  xslt:transform($in, $style, <xslt:parameters><xslt:v>1</xslt:v></xslt:parameters>),
 
  xslt:transform($in, $style, map { "v" := 1 })
 
)
 
 
</pre>
 
</pre>
  
'''variable.xslt'''
+
'''variable.xsl'''
<pre class="brush:xslt">
+
<pre lang="xslt">
 
<xsl:stylesheet version='1.0'
 
<xsl:stylesheet version='1.0'
 
     xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
 
     xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
Line 133: Line 194:
  
 
'''Result:'''
 
'''Result:'''
<pre class="brush:xml">
+
<pre lang="xml">
 
<v>1</v>
 
<v>1</v>
 
<v>1</v>
 
<v>1</v>
 
</pre>
 
</pre>
  
[[Category:XQuery]]
+
'''Example 4: XSL transformation, yielding a result and info messages'''
 +
 
 +
'''Query:'''
 +
<pre lang='xquery'>
 +
xslt:transform-report(
 +
  <_/>,
 +
  <xsl:transform version='2.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
 +
    <xsl:template match='/'>
 +
      <xsl:message><msg>START...</msg></xsl:message>
 +
      <xml>123</xml>
 +
      <xsl:message select='4, 5, "...END"'/>
 +
    </xsl:template>
 +
  </xsl:transform>
 +
)
 +
</pre>
 +
 
 +
'''Result:'''
 +
<pre lang='xquery'>
 +
map {
 +
  "messages": ([<msg>START...</msg>], ["4 5 ...END"]),
 +
  "result": <xml>123</xml>
 +
}
 +
</pre>
 +
 
 +
=Errors=
 +
 
 +
{| class="wikitable" width="100%"
 +
! width="110"|Code
 +
|Description
 +
|- valign="top"
 +
|{{Code|error}}
 +
| An error occurred during the transformation process.
 +
|}
 +
 
 +
=Changelog=
 +
 
 +
;Version 9.7
 +
* Added: {{Function||xslt:transform-report}}
 +
 
 +
;Version 9.2
 +
 
 +
* Updated: Support for XML Catalog files added.
 +
 
 +
;Version 9.0
 +
 
 +
* Updated: {{Function||xslt:transform}}, {{Function||xslt:transform-text}}: {{Code|$options}} argument added.
 +
* Updated: error codes updated; errors now use the module namespace
 +
 
 +
;Version 7.6
 +
 
 +
* Added: {{Function||xslt:transform-text}}
 +
* Updated: {{Function||xslt:transform}} returned error code
 +
 
 +
;Version 7.3
 +
 
 +
* Updated: $xslt:processor → {{Function||xslt:processor}}, $xslt:version → {{Function||xslt:version}}

Latest revision as of 18:38, 1 December 2023

This XQuery Module contains functions and variables to perform XSL transformations.

By default, this module uses Java’s XSLT 1.0 Xalan implementation to transform documents. XSLT 3.0 is used if the Saxon XSLT Processor is found in the class path (e.g. by placing the library files in the lib/custom directory). A specific transformer can be specified by assigning a classpath to the system property javax.xml.transform.TransformerFactory with the -D flag on the command line, or directly in Java:

System.setProperty(
  "javax.xml.transform.TransformerFactory",
  "org.custom.xslt.TransformerFactoryImpl");

Context ctx = new Context();
String result = new XQuery("xslt:transform('...', '...')").execute(ctx);
...
ctx.close();

Conventions[edit]

All functions and errors in this module are assigned to the http://basex.org/modules/xslt namespace, which is statically bound to the xslt prefix.

Functions[edit]

xslt:processor[edit]

Signature xslt:processor() as xs:string
Summary Returns the name of the applied XSLT processor ("Java", "Saxon EE", "Saxon PE", "Saxon HE"). If a system property was assigned that points to an existing implementation other than Saxon, the classpath is returned instead.

xslt:version[edit]

Signature xslt:version() as xs:string
Summary Returns the supported XSLT version ("1.0", "3.0"). An empty string is returned if a classpath in the system property points to an existing implementation other than Saxon.

xslt:transform[edit]

Signature
xslt:transform(
  $input       as item(),
  $stylesheet  as item(),
  $arguments   as map(*)?  := map { },
  $options     as map(*)?  := map { }
) as node()
Summary Transforms the document specified by $input, using the XSLT template specified by $stylesheet, and returns the result as node. $input and $stylesheet can be specified as
  • xs:string, containing the stylesheet URI,
  • xs:string, containing the document in its string representation, or
  • node(), containing the document itself.

XML Catalog files will be considered when resolving URIs. Variables can be bound to a stylesheet via $arguments (only strings are supported when using XSLT 3.0 and Saxon). The following $options are available:

  • cache: cache XSLT transformer (speeds up repeated transformations, but increases memory consumption)
Error error: an error occurred during the transformation process.

xslt:transform-text[edit]

Signature
xslt:transform-text(
  $input       as item(),
  $stylesheet  as item(),
  $arguments   as map(*)?  := map { },
  $options     as map(*)?  := map { }
) as xs:string
Summary Transforms the document specified by $input, using the XSLT template specified by $stylesheet, and returns the result as string. The semantics of $params and $options is the same as for xslt:transform.
Error error: an error occurred during the transformation process.

xslt:transform-report[edit]

Signature
xslt:transform-report(
  $input       as item(),
  $stylesheet  as item(),
  $arguments   as map(*)?  := map { },
  $options     as map(*)?  := map { }
) as xs:string
Summary Transforms the document specified by $input, using the XSLT template specified by $stylesheet, and returns a map with the following keys:
  • result: The transformation result: One or more document nodes, or (if the result cannot be converted to XML) an item of type xs:untypedAtomic.
  • messages: Informational output generated by xsl:message elements: A sequence of arrays. The arrays consist of XML elements, or (for those messages that cannot be converted to XML) items of type xs:untypedAtomic.

The semantics of $params and $options is the same as for xslt:transform.
For the moment, messages can only be returned with recent versions of Saxon.

  • error (optional): An error string, which would be raised as an error by the other functions of this module.

Examples[edit]

Example 1: XSL transformation, with XML and XSL supplied as nodes

Query:

(: Outputs the result as html. :)
declare option output:method 'html';

let $in :=
  <books>
    <book>
      <title>XSLT Programmer’s Reference</title> 
      <author>Michael H. Kay</author> 
    </book>
    <book>
      <title>XSLT</title> 
      <author>Doug Tidwell</author> 
      <author>Simon St. Laurent</author>
      <author>Robert Romano</author>
    </book>
  </books>
let $style :=
  <xsl:stylesheet version='3.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
  <xsl:output method='xml'/>
    <xsl:template match="/">
<html>
  <body>
    <div>
      <xsl:for-each select='books/book'>
      • <b><xsl:apply-templates select='title'/></b>: <xsl:value-of select='author'/><br/>
      </xsl:for-each>
    </div>
  </body>
</html>
    </xsl:template>
  </xsl:stylesheet>

return xslt:transform($in, $style)

Result:

<html>
  <body>
    <div>
      • <b>XSLT Programmer’s Reference</b>: Michael H. Kay<br>
      • <b>XSLT</b>: Doug Tidwell<br>
    </div>
  </body>
</html>

Example 2: Textual XSL transformation

Query:

xslt:transform-text(<dummy/>, 'basic.xslt')

basic.xslt

<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
  <xsl:template match="/">123</xsl:template>
</xsl:stylesheet>

Result:

123

Example 3: XSL transformation with variable assignment

Query:

let $in := <dummy/>
let $style := doc('variable.xsl')
return xslt:transform($in, $style, map { "v": 1 })

variable.xsl

<xsl:stylesheet version='1.0'
    xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
  <xsl:param name='v'/>
    <xsl:template match='/'>
      <v><xsl:value-of select='$v'/></v>
    </xsl:template>
</xsl:stylesheet>

Result:

<v>1</v>
<v>1</v>

Example 4: XSL transformation, yielding a result and info messages

Query:

xslt:transform-report(
  <_/>,
  <xsl:transform version='2.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
    <xsl:template match='/'>
      <xsl:message><msg>START...</msg></xsl:message>
      <xml>123</xml>
      <xsl:message select='4, 5, "...END"'/>
    </xsl:template>
  </xsl:transform>
)

Result:

map {
  "messages": ([<msg>START...</msg>], ["4 5 ...END"]),
  "result": <xml>123</xml>
}

Errors[edit]

Code Description
error An error occurred during the transformation process.

Changelog[edit]

Version 9.7
Version 9.2
  • Updated: Support for XML Catalog files added.
Version 9.0
Version 7.6
Version 7.3