Reputation: 29693
I have XML data
<logData>
<log>
<id>1</id>
</log>
<log>
<id>2</id>
</log>
<log>
<id>3</id>
</log>
<log>
<id>4</id>
</log>
</logData>
I want get only part of logs using xslt transformation using fn:subsequence function
here is my xslt
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:fn="http://www.w3.org/2006/xpath-functions" version="1.0" >
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="/logData" >
<xsl:element name="log">
<xsl:copy-of select="fn:subsequence(./log, 2, 3)"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
and I get
ERROR: 'The first argument to the non-static Java function 'subsequence' is not a valid object reference.'
I am using Java transformation API, part of Java SE 1.6.
Can you help me?
Upvotes: 1
Views: 584
Reputation: 163458
Since you are using Java, all you need to do is to ensure that your code loads an XSLT 2.0 processor instead of XSLT 1.0. The default XSLT processor in the JDK only supports XSLT 1.0.
Download Saxon-HE, and set the system property
-Djavax.xml.transform.TransformerFactory=net.sf.saxon.TransformerFactoryImpl
and your code should work.
(Of course, as Dimitre shows, this transformation can be done easily enough in XSLT 1.0. But by sticking to XSLT 1.0 you are are trying to move with your feet tied together at the ankles. XSLT 2.0 is vastly more powerful and easier to use, and it's available in your environment, so use it.)
Upvotes: 1
Reputation: 243529
<xsl:copy-of select="fn:subsequence(./log, 2, 3)"/>
The function subsequence()
is defined in XPath 2.0 and is available only in an XSLT 2.0 processor.
In XSLT 1.0 use:
<xsl:copy-of select="log[position() > 1 and not(position() > 4)]"/>
Here is a complete transformation:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<xsl:copy-of select="log[position() > 1 and not(position() > 4)]"/>
</xsl:template>
</xsl:stylesheet>
When this is applied on the provided XML document:
<logData>
<log>
<id>1</id>
</log>
<log>
<id>2</id>
</log>
<log>
<id>3</id>
</log>
<log>
<id>4</id>
</log>
</logData>
the wanted, correct result is produced:
<log>
<id>2</id>
</log>
<log>
<id>3</id>
</log>
<log>
<id>4</id>
</log>
Upvotes: 1