-1

Is there any facility available in XSLT 1.0 or exslt to generate a result document so that it also creates the directory(ies) in the path if they are not present? Or do I have to create the directory separately before generating the output document?

UPDATE

I am using Perl to perform the XSLT 1.0 transformation. Here is the code that I use.

#!/usr/local/bin/perl -w

use strict;
use warnings;
use File::Path;
use File::Spec;
use File::Basename;
use XML::LibXSLT;
use XML::LibXML;

my $isfile;

my ($xmlfile,$xsltfile,$samplefile) = qw/ Example.xml trans.xsl sample.xml/;

if(-f $samplefile)
{
    $isfile = "true";
    print "File is present\n";
}
else
{
    $isfile = "false";
    print "File is absent\n";
}

my %args = ( "isfile" => $isfile ); 
my $xslt = XML::LibXSLT->new;
my $stylesheet = $xslt->parse_stylesheet_file($xsltfile);
my $results    = $stylesheet->transform_file($xmlfile,XML::LibXSLT::xpath_to_string(%{args}));

0;

And my XSL file is as follows

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xalan="http://xml.apache.org/xslt"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:exsl="http://exslt.org/common"
    extension-element-prefixes="exsl">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" media-type="text/xml"/>

    <xsl:param name="isfile"/>

    <xsl:template match="/">      
            <xsl:if test="$isfile = 'true'">  
                <exsl:document href = "/home/USER/Documents/XSLT/Dir1/Dir2/Dir3/outputfile1.xml" method="xml" version="1.0" encoding="UTF-8" indent="yes">                  
                    Article:- <xsl:value-of select="/Article/Title"/>
                    Authors:- <xsl:apply-templates select="/Article/Authors/Author"/>
                </exsl:document>
            </xsl:if>
        </xsl:template>

        <xsl:template match="Author">
            <exsl:document href = "outputfile2.xml" method="xml" version="1.0" encoding="UTF-8" indent="yes">                  
                always Generate this output!! <xsl:value-of select="." />
            </exsl:document>
        </xsl:template>
    </xsl:stylesheet>

I get following errors.

runtime error: file trans.xsl line 24 element document
Directory creation for /home/USER/Documents/XSLT/Dir1/Dir2/Dir3/outputfile1.xml refused
runtime error: file trans.xsl line 24 element document
xsltDocumentElem: write rights for /home/USER/Documents/XSLT/Dir1/Dir2/Dir3/outputfile1.xml denied
 at Transform.pl line 29

Even when I change the path as Dir1/Dir2/Dir3/outputfile1.xml (so that it uses the current directory where I have given full permissions),in the xsl file, I get following errors.

runtime error: file trans.xsl line 24 element document
Directory creation for Dir1/Dir2/Dir3/outputfile1.xml refused
runtime error: file trans.xsl line 24 element document
xsltDocumentElem: write rights for Dir1/Dir2/Dir3/outputfile1.xml denied
 at Transform.pl line 29

Does the libxslt in Perl 5.8.8 not support the directory creation?

Recker
  • 1,915
  • 25
  • 55
  • Consider adding a tag for Perl to get some help specific to Perl and libxslt. I am not sure many of the readers seeing questions on XSLT use Perl to run the stylesheet. – Martin Honnen Aug 24 '16 at 13:33
  • Updated the question. – Recker Aug 24 '16 at 13:45
  • 1
    http://search.cpan.org/dist/XML-LibXSLT/LibXSLT.pm says in the section "XML::LibXSLT::Security": "By default, create_dir is not allowed. To enable it a callback must be registered." so it look as if you have to allow it explicitly as described there by setting up a callback returning `1`. – Martin Honnen Aug 24 '16 at 14:33

2 Answers2

1

I tried

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:exsl="http://exslt.org/common"
    extension-element-prefixes="exsl"
    exclude-result-prefixes="xs exsl"
    version="1.0">

    <xsl:template match="/">
        <exsl:document href="outputTest1/test2016082403Result.xml">
            <foo>bar</foo>
        </exsl:document>
    </xsl:template>

</xsl:stylesheet>

with xsltproc as provided with oXygen and the directory outputTest1 was created and contained the file test2016082403Result.xml so at least with xsltproc/libxslt the directory creation seems to be supported. I am not aware on any other XSLT 1.0 processor supporting exsl:document anyway.

Martin Honnen
  • 160,499
  • 6
  • 90
  • 110
1

Yes, one can write/read file and create directory in XSLT 1.0 if you are using Perl for triggering the transformation. As mentioned by Martin Honnen, all I had to do was add the few security callbacks such that it would all the XSLT engine to perform the file operations. Perl script now looks like

#!/usr/local/bin/perl -w

use strict;
use warnings;
use File::Path;
use File::Spec;
use File::Basename;
use XML::LibXSLT;
use XML::LibXML;

my $isfile;

my ($xmlfile,$xsltfile,$samplefile) = qw/ Example.xml trans.xsl sample.xml/;

if(-f $samplefile)
{
    $isfile = "true";
    print "File is present\n";
}
else
{
    $isfile = "false";
    print "File is absent\n";
}

my %args = ( "isfile" => $isfile ); 
my $xslt = XML::LibXSLT->new;
my $stylesheet = $xslt->parse_stylesheet_file($xsltfile);

    my $security = XML::LibXSLT::Security->new();
    $security->register_callback( read_file  => sub { return 1;} );
    $security->register_callback( write_file => sub { return 1;} );
    $security->register_callback( create_dir => sub { return 1;} );
    $stylesheet->security_callbacks( $security );

my $results    = $stylesheet->transform_file($xmlfile,XML::LibXSLT::xpath_to_string(%{args}));

0;
Recker
  • 1,915
  • 25
  • 55