How can you use xpath-functions with XSLT 2.0? - xslt

In order to use xpath-functions (specifically the fn part), I included the respective namespace into my xslt stylesheet, like so:
<xsl:stylesheet
version="2.0"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
>
As specified by W3C.
However, when I use fn:document-uri, my XSLT engines tell me I called an unknown function/extension:
<xsl:variable name="uri" select="fn:document-uri()" />
Opera says:
This document had an invalid XSLT stylesheet. Error message from the XSLT engine:
Error: XPath expression compilation failed: fn:document-uri()
Details: compilation error (characters 1-17, "fn:document-uri()"): unknown function called: '{ http://www.w3.org/2005/xpath-functions, document-uri }'
Firefox says:
Error during XSLT transformation: An unknown XPath extension function was called.
And xsltproc refuses transformation, because of xslt 2.0.
So, how do I specify the fn namespace properly?

The problem is that you are using an XSLT 1.0 processor and an XSLT 1.0 processor doesn't know (and must not know) anything about XPath 2.0 functions.
If you use a real XSLT 2.0 processor, you don't even have to specify the function namespace -- it is a default namespace for any unprefixed function name.
For example, this XSLT 2.0 transformation:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:sequence select="document-uri(.)" />
<xsl:text>
</xsl:text>
<xsl:sequence select="document-uri(document(''))" />
</xsl:template>
</xsl:stylesheet>
when executed with Saxon 9.1.5 under the XSelerator, produces correctly the URLs of the source XML document and the stylesheet itself:
file:/C:/Program%20Files/Java/jre6/bin/marrowtr.xml
file:/C:/Program%20Files/Java/jre6/bin/marrowtr.xsl

Related

Is it possible to store the parser error message in variable using xslt2.0 or xslt 3.0

I am doing transform xml file using xslt and I want to display the error message of xslt parser in an element
Note: Error message should be original of parser message
I am not sure there is a way to capture XML parsing errors of the primary input document to an apply-templates based XSLT 3 transformation but in general XSLT 3 with xsl:try/xsl:catch allows you to capture and handle run-time errors, so assuming you can organize the rest of your code (for instance by using a named template as the starting point) to load/parse any XML documents with the doc or document function then you can use try/catch to handle parsing errors. An example is https://xsltfiddle.liberty-development.net/ej9EGcg/2
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:err="http://www.w3.org/2005/xqt-errors"
exclude-result-prefixes="#all"
version="3.0">
<xsl:template match="/">
<root>
<xsl:try>
<xsl:variable name="doc1" select="doc('https://raw.githubusercontent.com/martin-honnen/martin-honnen.github.io/master/xslt/2019/test2019032601.xml')"/>
<xsl:value-of select="count($doc1//item)"/>
<xsl:catch>Error code: <xsl:value-of select="$err:code"/>
Reason: <xsl:value-of select="$err:description"/>
</xsl:catch>
</xsl:try>
</root>
</xsl:template>
</xsl:stylesheet>
which, depending on your needs, can also be reduced to directly use the relevant XPath expression with the select attribute of the xsl:try element e.g. https://xsltfiddle.liberty-development.net/ej9EGcg/3
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:err="http://www.w3.org/2005/xqt-errors"
exclude-result-prefixes="#all"
version="3.0">
<xsl:template match="/">
<root>
<xsl:try select="count(doc('https://raw.githubusercontent.com/martin-honnen/martin-honnen.github.io/master/xslt/2019/test2019032601.xml'))">
<xsl:catch>Error code: <xsl:value-of select="$err:code"/>
Reason: <xsl:value-of select="$err:description"/>
</xsl:catch>
</xsl:try>
</root>
</xsl:template>
</xsl:stylesheet>

Getting error "XPath is invalid" for "hours-from-duration($duration)"

I need help with one of my issues. I am new to XSLT. Right now I am trying to write an XSLT which will generate text output (example: "01:30").
In my XSLT 2.0, I am calling the XPath function hours-from-duration($duration) and this function is throwing the error
XPath is invalid
I can also see the above error in the following logs. Please help me with my issues. Thanks...
16:01:39,403 ERROR [main] JAXPSAXProcessorInvoker - Error checking type of the expression 'funcall(hours-from-duration, [variable-ref(duration/node-set)])'.
16:01:39,404 ERROR [main] JAXPSAXProcessorInvoker - Could not compile stylesheet
javax.xml.transform.TransformerConfigurationException: Could not compile stylesheet at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl.newTemplates(TransformerFactoryImpl.java:858) at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl.newTransformer(TransformerFactoryImpl.java:648)
My XSLT:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:date="http://exslt.org/dates-and-times"
xmlns:str="http://exslt.org/strings"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
version="1.0" xmlns:xalan="http://xml.apache.org/xslt">
<xsl:output method="text" />
<xsl:variable name="request" select="/*[local-name()='Payout']/*[local-name()='Request']" />
<xsl:variable name="duration" select="$request/Time" />
<xsl:template match="/">
<xsl:value-of select="(hours-from-duration($duration))"/>
<xsl:text>:</xsl:text>
<xsl:value-of select="(minutes-from-duration($duration))"/>
</xsl:template>
</xsl:stylesheet>
XML Input:
<Payout>
<Request Commit="true" Transaction="false">
<Month>JAN</Month>
<Time>P01H30M33S</Time>
</Request>
</Payout>
Your duration value is invalid. It is missing a "T". It should be PT01H30M33S.
hours-from-duration() is an XPath 2.0 function. You are using Xalan, which only supports XSLT 1.0 and XPath 1.0.
Furthermore, these functions expect an object of type xs:duration. You are passing it a node (a Time element). If you switch to an XSLT 2.0 processor, you will need either (a) to make sure the processor is schema-aware and Time is validated as an xs:duration, or (b) to convert it to type xs:duration explicitly, by calling xs:duration(Time).
And of course you will need to make sure it's a valid duration as pointed out by #MadsHansen

Usage of saxon:recognize-binary

When I try to run this XSLT style sheet (adapted from http://www.oxygenxml.com/archives/xsl-list/201001/msg00361.html) with Saxon 9.1.0.8 or Saxon-HE 9.5.1.3J, I get an empty output file.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:saxon="http://saxon.sf.net/" version="2.0">
<xsl:output saxon:recognize-binary="yes" method="text"/>
<xsl:template match="/">
<?hex 07?>
<xsl:processing-instruction name="hex" select="'07'"/>
</xsl:template>
</xsl:stylesheet>
From the Saxon documentation and the message mentioned above, I would have expected that the output is a string containing one (or two) ^G characters. Why did I not get any output at all?
Custom serialization requires Saxon-PE (or EE).
You should've gotten an error similar to this:
Transformation failed: Requested feature (custom serialization
{http://saxon.sf.net/}recognize-binary) requires Saxon-PE
http://saxonica.com/documentation/index.html#!extensions
I tried it with Saxon-EE 9.3.0.5 and it works.
Note that you need the xsl:processing-instruction form. Literal PIs in a stylesheet are stripped out, they do not cause processing instructions to be sent to the output.

XSLT: :result-document

I have an XSL which generates a XML file
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="html" indent="yes"/>
<xsl:template match="/">
<xsl:variable name="filename" select="concat('TextTypes','.html')" />
<xsl:result-document method="html" href="{$filename}">
<font name="{$truncatedFont}" size="{$truncatedSize}" style="{#styleOverride}" env="{$env}" lang="{#language}" />
</xsl:result-document>
</xsl:template>
</xsl:stylesheet>
When I run the XSLT i get the error:
ERROR: 'Unsupported XSL element 'http://www.w3.org/1999/XSL/Transform:result-document''
Error during transformation
javax.xml.transform.TransformerException: java.lang.RuntimeException: Unsupported XSL element 'http://www.w3.org/1999/XSL/Transform:result-document'
I have specified ny XSLT verision as 2.0. I am confused on why i get this error. Please help.
XSLT 2.0 is only supported by a few XSLT processors, I think with Java there is only Saxon 9 and with IBM's websphere you can also use IBM's XSLT 2.0 processor but the XSLT processor in the Oracle respectively SUN JRE and JDK is based an Apache Xalan and only supports XSLT 1.0.
Looks like your xslt processor does not support version 2.0.
It depends on how you're running your XSLT nishMaria.
If you can daisy chain XSLT then you can process the input document multiple times to produce multiple different output files or produce one output file with all the desired output then pass this file through a number of XSLT's each of which just selects part of the output.

XSLT date-time() function is unknown in ALTOVA XmlSpy

Good day! I downloaded Altova XMLSpy trial, installed FOP 0.95 and tried to perform XSLT (version 1.0) transformation. My template is valid but during the transformation it fails on the line containing "date-time()" function:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:dt="http://exslt.org/dates-and-times" xmlns:exsl="http://exslt.org/common" extension-element-prefixes="dt exsl">
<xsl:output method="html" encoding="utf-8" indent="yes"/>
<xsl:template match="/">
<html>
<body>
<xsl:value-of select="dt:date-time()"/>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
The error message is:
Error in XPath expression
Unknown function - Name and number of arguments do not match any function signature in
the static context - 'http://exslt.org/dates-and-times:date-time'
Please how to make this function available? I'm sure this function exists. The template works for example in this online XSLT tester: http://markbucayan.appspot.com/xslt/index.html
Thank you in advance! Vojtech
UPDATE: I installed SAXON 9 (both HE and EE), configured ALTOVA to use it but again the same error.
If you are using Altova or saxon you can use XSLT2 rather than XSLT1 so do not need to load the EXSLT extensions, xpath2 has this function built in
select="current-dateTime()"
http://www.w3.org/TR/xpath-functions/#func-current-dateTime
`<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" extension-element-prefixes="msxsl" xmlns:local="urn:local>
<msxsl:script language="CSharp" implements-prefix="local">
public string dateTimeNow()
{
return DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ssZ");
}
</msxsl:script> </xsl:stylesheet>`
and then use it like this <xsl:param name="dnes" select="local:dateTimeNow()"/>
Please use Altova xml spy 9 version which support XSL 2.0.
Thanks
Aditya