Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use XSLT 3.0 from a Java application?

Tags:

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 ?

like image 322
Wilvasini Avatar asked Jun 28 '17 08:06

Wilvasini


People also ask

How do I use an XSLT file?

Add the XSLT style sheet using the Properties window. With the XML file open in the editor, right-click anywhere in the editor and choose Properties. In the Properties window, click in the Stylesheet field and choose the browse button (...). Select the XSLT style sheet, and then choose Open.

Can we use JavaScript in XSLT?

JavaScript can run XSLT transformations through the XSLTProcessor object. Once instantiated, an XSLTProcessor has an XSLTProcessor. importStylesheet() method that takes as an argument the XSLT stylesheet to be used in the transformation. The stylesheet has to be passed in as an XML document, which means that the .


1 Answers

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();
like image 161
Martin Honnen Avatar answered Oct 11 '22 09:10

Martin Honnen