Using Saxon Extensions

Here should go questions about transforming XML with XSLT and FOP.
William
Posts: 42
Joined: Sun Jul 15, 2012 12:26 pm
Location: London

Using Saxon Extensions

Post by William »

Hello,

I have a jar file that contains a class I want to make use of within my XPath 2 transformer, but I'm confused on how to access it, there is nothing to be found in Michael Kay's 2004 "XPath 2.0" and what is available appears dated (v1).

At present the jar file is on a web site but I can easily run it local if needed (I'm the author of said jar file) but access via HTTP would be preferred as I'll always have the latest version then.

Can anyone provide me with sample XSLT or appropriate links please?

I am of course using Saxon-EE 9.4.0.3.

--
William
William
Posts: 42
Joined: Sun Jul 15, 2012 12:26 pm
Location: London

Re: Using Saxon Extensions

Post by William »

OK, I now have this at the stage where it can be executed but when I do I get oXygen telling me that an exception has occurred. Using the original template and processed with Saxon 6.5.5 I get my XML generated without error.

However when I 'upgrade' to XPath 2 using a near duplicate of this template and processed with Saxon-EE 9.4.0.3 I get the aforementioned exception. I'm confused, as the only changes are the use of XPath 2 specific functions, and the parser. Is this my fault?

For what it's worth here's the exception :

Code: Select all


Exception in extension function {public src.functions.BlockCalculator(java.lang.String,java.lang.String)}: java.lang.IllegalArgumentException:  - 
--
William
adrian
Posts: 2855
Joined: Tue May 17, 2005 4:01 pm

Re: Using Saxon Extensions

Post by adrian »

Hi,

Could you please provide the XSL or a sample of it?
I need to see the namespace declarations on the stylesheet root and the way you call the extension.

Also, did you declare the extension function in a Saxon configuration file?

Regards,
Adrian
Adrian Buza
<oXygen/> XML Editor, Schema Editor and XSLT Editor/Debugger
http://www.oxygenxml.com
William
Posts: 42
Joined: Sun Jul 15, 2012 12:26 pm
Location: London

Re: Using Saxon Extensions

Post by William »

Hi Adrian,

I hope this is what you mean / need.

Declaration for XPath v2

Code: Select all


<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xalan="http://xml.apache.org/xslt"
xmlns:src="xalan://src.functions.BlockCalculator"
exclude-result-prefixes="xs src xalan" >
and for XPath v1

Code: Select all


<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xalan="http://xml.apache.org/xslt"
xmlns:src="xalan://src.functions.BlockCalculator"
exclude-result-prefixes="xs src xalan" >
Usage is the same for both :

Code: Select all


<xsl:param name="currDate" />
<xsl:param name="startDate" />
<!-- Instanciate the class -->
<xsl:variable name="Calculator" select="src:new($startDate, $currDate)" />
...
<xsl:template ...>
...
<!-- This is the line that fails in XPath v2 -->
<elementName blocktwo="{src:getBlockTwo($Calculator)}"/>
...
</xsl:template>
As regards the declaration of the extension I confess to not knowing what you mean, but I have configured the Transform Scenarios to include the jar file (on local file system) and set the values for the two parameters referenced above.

--
William
adrian
Posts: 2855
Joined: Tue May 17, 2005 4:01 pm

Re: Using Saxon Extensions

Post by adrian »

Hi,

I believe you mean XSLT 2.0 and XSLT 1.0. XPath is a different concept that is used within XSLT and XQuery: http://www.w3schools.com/xpath/

I see that you are declaring Xalan extensions (even for XSLT 2.0), but you say you are using Saxon-EE. Obviously that won't work. You need to declare java extensions for Saxon-PE/EE 9: xmlns:ns="java:fully.qualified.class.Name"

e.g. XSLT 2.0

Code: Select all

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:src="java:src.functions.BlockCalculator"
exclude-result-prefixes="xs src" >
The current usage should work correctly with these declarations.

Make sure you've added the .jar with the compiled java classes to the Extensions (button) from the transformation scenario editing dialog.

Regards,
Adrian
Adrian Buza
<oXygen/> XML Editor, Schema Editor and XSLT Editor/Debugger
http://www.oxygenxml.com
William
Posts: 42
Joined: Sun Jul 15, 2012 12:26 pm
Location: London

Re: Using Saxon Extensions

Post by William »

adrian wrote:Hi,

I believe you mean XSLT 2.0 and XSLT 1.0. XPath is a different concept that is used within XSLT and XQuery: http://www.w3schools.com/xpath/
I do indeed, caused by an error in the wetware.
adrian wrote: I see that you are declaring Xalan extensions (even for XSLT 2.0), but you say you are using Saxon-EE. Obviously that won't work.
Well actually it does and would have worked (and saved this posting) if I had actually set the param values in the Scenario!
adrian wrote: You need to declare java extensions for Saxon-PE/EE 9: xmlns:ns="java:fully.qualified.class.Name"

e.g. XSLT 2.0

Code: Select all

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:src="java:src.functions.BlockCalculator"
exclude-result-prefixes="xs src" >
The current usage should work correctly with these declarations.

Make sure you've added the .jar with the compiled java classes to the Extensions (button) from the transformation scenario editing dialog.

Regards,
Adrian
I have thank you and it works too. (Now the dates are set!)

But I still get a warning.

Code: Select all

A variable with no following sibling instructions has no effect
Regarding this line :

Code: Select all

<xsl:variable name="c" select="src:calcBlock($Calculator)"/>
which is itself contained in an <xsl:template> and is the last line of said template.

Is there anything I can do about this? As the transformer will be going in to a Java application and I would prefer not to have any warnings at all.

I'm willing to send (to support) the Java source, XSLT and XML input file if needed.

As always, "thank you" for your help.

--
William
adrian
Posts: 2855
Joined: Tue May 17, 2005 4:01 pm

Re: Using Saxon Extensions

Post by adrian »

That warning is Saxon's way of telling you that the variable assignment will never be performed because there is nothing following it (that could use that variable).

BTW, why assign a variable if you won't use it in any way?
Note that Saxon 9 won't initialize any unused variables and it may not always warn you about this.

Regards,
Adrian
Adrian Buza
<oXygen/> XML Editor, Schema Editor and XSLT Editor/Debugger
http://www.oxygenxml.com
William
Posts: 42
Joined: Sun Jul 15, 2012 12:26 pm
Location: London

Re: Using Saxon Extensions

Post by William »

adrian wrote:That warning is Saxon's way of telling you that the variable assignment will never be performed because there is nothing following it (that could use that variable).
This of course makes perfect sense.
adrian wrote:BTW, why assign a variable if you won't use it in any way?
Note that Saxon 9 won't initialize any unused variables and it may not always warn you about this.

Regards,
Adrian
Hello Adrian,

What I'm actually doing (or thought I was) is to call a function on the BlockCalculator class having set various values in other similar calls in the lines above.

Code: Select all


<xsl:template name="functions">
<xsl:param name="type" />
<xsl:variable name="f" select="src:setSD($Calculator, @from)" />
<xsl:variable name="u" select="src:setED($Calculator, @until)" />
<xsl:variable name="h" select="src:setH($Calculator, $type = 'g')"/>
<xsl:variable name="e" select="src:setE($Calculator, @period = 'WD')"/>
<xsl:variable name="c" select="src:calcBlock($Calculator)"/>
</xsl:template>
This template is then used like this:

Code: Select all


<nodeName>
<xsl:for-each select="./xxxx">
<xsl:call-template name="functions">
<xsl:with-param name="type" select="'g'"/>
</xsl:call-template>
<elementName blocktwo="{src:getBlockTwo($Calculator)}"/>
...
<xsl:for-each>
</nodeName>
I'm assuming in my naivety that all of the functions are getting called with their applicable value on each iteration. The last call (the one causing the warning) actually does the math and makes the calculated blocks available via the getBlockXXX method. Am I going about this the wrong way?

I'm only doing this as I have not found anything on the web that gives a solid grounding on this subject.

--
William :?
William
Posts: 42
Joined: Sun Jul 15, 2012 12:26 pm
Location: London

Re: Using Saxon Extensions

Post by William »

Hello.

This is driving me :x . I've added 'debug' code to my BlockCalculator class and redirected all System output to a file. When my transformer starts I see a call to the two parameter constructor.

However I never see messages from any other methods in the log file!

As I have had no denial nor confirmation that my approach is incorrect I am assuming that what I am doing is right. But of course my log file tells me different.

I have even moved the class function calls out of their template and call them directly:

Code: Select all


<nodeName>
<xsl:for-each select="./xxxx">
<xsl:variable name="f" select="src:setSD($Calculator, @from)" />
<xsl:variable name="u" select="src:setED($Calculator, @until)" />
<xsl:variable name="h" select="src:setH($Calculator, true())"/>
<xsl:variable name="e" select="src:setE($Calculator, @period = 'WD')"/>
<xsl:variable name="c" select="src:calcBlock($Calculator)"/>
<elementName blocktwo="{src:getBlockTwo($Calculator)}"/>
...
<xsl:for-each>
</nodeName>
None of the functions called above generate any output in the log file but the call to calcBlock(...) spews out NullPointerExceptions as my class's startDate member variable is null!

But of course this should have been set when setSD(...) was called, and as there is nothing in the log file recording the function call it explains why the value is null.

But what it doesn't explain is why the only methods that apparently gets called correctly are the parameterless ones.

Thinking about this I've just done a test and hard wired values for the getBlockXXX functions and true to form they return 99 and 22 as expected.

So this begs the question what's wrong with the way I'm passing parameter values to my functions?

--
William
adrian
Posts: 2855
Joined: Tue May 17, 2005 4:01 pm

Re: Using Saxon Extensions

Post by adrian »

Hi,

I've told you, Saxon 9 optimizes the code and never initializes unused variables. This means none of your extensions from the unused variables are called. It's all dead code.

Put the calls in something else rather than a variable declaration.
e.g.
xsl:if/@test
xsl:message/@select


Regards,
Adrian
Adrian Buza
<oXygen/> XML Editor, Schema Editor and XSLT Editor/Debugger
http://www.oxygenxml.com
William
Posts: 42
Joined: Sun Jul 15, 2012 12:26 pm
Location: London

Re: Using Saxon Extensions

Post by William »

Hi Adrian.

I've just taken time to give myself a "right good talking to" and promised myself not to embarrass me again.

One of those days I guess! Well that's my excuse.

--
William
Post Reply