How to use XSLT 3.0 from a Java application?
Asked Answered
J

1

6

The general java code i use to process XSLT and XML files are :

public static final String transformXmlDocument(String inputXmlString,
            File xsltFile) {

        TransformerFactory factory = TransformerFactory.newInstance();
        StreamSource xslt = new StreamSource(xsltFile);

        StreamSource text = new StreamSource(new StringReader(inputXmlString));
        StringWriter writer = new StringWriter();
        StreamResult textOP = new StreamResult(writer);

        try {
            Transformer transformer = factory.newTransformer(xslt);
            transformer.transform(text, textOP);
        } catch (TransformerConfigurationException e) {
            e.printStackTrace();
        } catch (TransformerException e2) {
            e2.printStackTrace();
        }
        String results = writer.toString();

        return results;
}

I have to process an XSLT of 3.0 version to use the following function :

parse-xml-fragment()

It throws error for this version of XSLT saying:

parse-xml-fragment() not found as a function

My input XML :

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<data>
  <![CDATA[<pi>hi</pi>]]>
</data>

XSLT code:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:xs="http://www.w3.org/2001/XMLSchema"
     xmlns:data="http://example.com/data"
     xmlns:text="http://exselt.net/text"
     xmlns:err="http://www.w3.org/2005/xqt-errors"
     exclude-result-prefixes="xs xsl data text err"
     version="3.0">

<xsl:output indent="yes"/>

     <xsl:template match="/">
         <xsl:variable name="sample">
            <xsl:copy-of select="parse-xml-fragment('&lt;gi&gt;surface&lt;/gi&gt;&lt;gi&gt;surface&lt;/gi&gt;&lt;gi&gt;surface&lt;/gi&gt;')" />
         </xsl:variable>
         <final>
            <xsl:copy-of select="data/pi"/>
             <xsl:for-each select="$sample/gi">
                 <pi><xsl:value-of select="."/></pi>
            </xsl:for-each> 
         </final>
     </xsl:template>

</xsl:stylesheet>

expected output:

<final>
    <pi>hi</pi>
    <pi>surface</pi>
    <pi>surface</pi>
    <pi>surface</pi>
  </final>

Can anyone please provide a solution ?

Jacintha answered 28/6, 2017 at 8:4 Comment(0)
W
6

You will need to make sure Saxon 9.8 HE or PE or EE is on your class path, HE is available on Sourceforge and Maven, the commercial editions PE and EE from saxonica.com. See http://saxonica.com/html/documentation/about/installationjava/installingjava.html and also http://saxonica.com/html/documentation/using-xsl/embedding/jaxp-transformation.html which recommend, once you have installed a particular edition, to use e.g. http://saxonica.com/html/documentation/javadoc/net/sf/saxon/TransformerFactoryImpl.html directly instead of relying on the JAXP class loader mechanism, so assuming you have Saxon 9.8 HE installed you can replace

    TransformerFactory factory = TransformerFactory.newInstance();

with

    TransformerFactory factory = new net.sf.saxon.TransformerFactoryImpl();
Wrist answered 28/6, 2017 at 8:15 Comment(12)
thanks for your quick response i added maven dependency : <!-- mvnrepository.com/artifact/net.sf.saxon/Saxon-HE --> <dependency> <groupId>net.sf.saxon</groupId> <artifactId>Saxon-HE</artifactId> <version>9.8.0-1</version> </dependency> Also replaced the TransformerFactory class as mentioned but i still get the error that it does not find parse-xml-fragment() as a function . I am i missing out anything ?Jacintha
Please edit your question and show minimal but complete snippets of XML input, XSLT code together with the exact error message allowing us to reproduce the problem. Are you not passing anything to parse-xml-fragment?Wrist
I have edited the question as requested sir when i run the same code from command line it works but not in eclipseJacintha
Please take your time to add minimal but complete snippets allowing us to reproduce the problem. <xsl:copy-of select"data/pi"/> is not even proper XML syntax. And I don't think that XSLT you have posted has 36 lines. Is there any chance you have other, older versions of Saxon too on the class path?Wrist
error message : javax.xml.transform.TransformerConfigurationException: Failed to compile stylesheet. 1 error detected. at net.sf.saxon.PreparedStylesheet.prepare(PreparedStylesheet.java:153) at net.sf.saxon.TransformerFactoryImpl.newTemplates(TransformerFactoryImpl.java:137) at net.sf.saxon.TransformerFactoryImpl.newTransformer(TransformerFactoryImpl.java:88) at com.translation.xslt.CustomXsltTransformer.transformXmlDocument(CustomXsltTransformer.java:60) at com.translationProcessRequest.TestClass.main(TestClass.java:105)Jacintha
sorry i have updated the error message and question accordinglyJacintha
Well, <xsl:copy-of select"data/pi"/> should be <xsl:copy-of select="data/pi"/> to be syntactically correct XML/XSLT. To make sense with your input semantically you rather want <xsl:copy-of select="data/parse-xml-fragment(.)/pi"/>.Wrist
As for "when i run the same code from command line it works but not in eclipse", someone else needs to help on finding out what is wrong with your setup in Eclipse, make sure you have only Saxon 9.8 in your project and not earlier versions as well.Wrist
Your comment is displaying a stack trace from Saxon so at least we know Saxon is being loaded. We don't know which version of Saxon, and my suspicion is that it isn't 9.8 because the line numbers don't fit. The stack trace isn't much use (it only says that compilation errors were found): what you really need is the log file showing what the compilation errors are. That will probably be somewhere in your Eclipse configuration. But I think the compile errors will only tell you that XSLT 3.0 constructs aren't recognized, which is what you would expect if the wrong version of Saxon has been loadedEthelinda
To find out what version of Saxon is on the classpath, call the static method net.sf.saxon.Version.getProductVersion().Ethelinda
i get version 8.9 in maven i have added : <version>9.8.0-1</version>Jacintha
following is the whole info printed from eclipse : xslt version 2.0 product name SAXON product version 8.9 my xslt version is not 3.0 how do i update it ?Jacintha

© 2022 - 2024 — McMap. All rights reserved.