Project

Profile

Help

Call other XSLT processes?

Added by Syd Bauman about 7 years ago

First, an apology if this is an obvious question for Javascript-speakers. I don't speak Javascript.

Is there a way to call other XSLT 2 programs from within a SaxonCE stylesheet? I'd like to be able to manage a complete reading interface from within XSLT 2. In which case, I'd have a single input XML document, and I'd like to present the user with several completely different transformations of that input, based on which button she clicks. I.e. the driver stylesheet being executed in her browser by SaxonCE would present her with several buttons, and each template that matches a button mode=onclick would execute a different transform on ixsl:source().

I'm pretty confident I can figure out how to do this calling a different template of the current SaxonCE-executed stylesheet based on which button was clicked. So if I'm willing to jam all the desired transforms into one large program, I can do the right thing from the user perspective. And if xsl:include and xsl:import work from within CE, I could store the code in separate files, which would make it easier to manage. But, in part because I always get a bit confused importing and including lots of stuff, I think it would make management easier if I could just call completely separate stylesheets. Is that possible? Or is there some other better way of doing this sort of thing?

Thanks to Saxonica for CE, and thanks to all for your consideration.


Replies (2)

RE: Call other XSLT processes? - Added by Michael Kay about 7 years ago

Well, you can call Javascript from XSLT, and you can invoke an XSLT transformation from Javascript, so it's certainly possible via that route.

The logic we use for doing this in the test driver is something like this:

        <xsl:variable name="cmd"
            select="js:makeCommand((

'stylesheet', $stylesheet, 'source', $source, 'initialTemplate', $initial-template, 'initialMode', $initial-mode ))"/>

        <xsl:variable name="result"
            select="if ($isHTMLUpdate) then js:update($cmd) else js:transform($cmd)"
            as="node()?"/>

where the relevant JS functions are

var transform = function (command) { command.method = "transformToDocument"; var proc = Saxon.run(command); return proc.getResultDocument(''); };

var update = function (command) { Saxon.run(command); };

/*

  • Create command object from XSLT name/value pair sequence */ var makeCommand = function (props) { cmd = {}; for (x = 0; x < props.length; x += 2) { if (props[x + 1] != null && props[x + 1].length != 0) { cmd[props[x]] = props[x + 1]; } } return cmd; };

RE: Call other XSLT processes? - Added by Eric van der Vlist about 7 years ago

Hi Sid,

Thanks to the extensions of Saxon CE, the code shared by Mike can also be written in XSLT!

If you use a "script element to run a transformation":http://www.saxonica.com/ce/user-doc/1.1/index.html#!starting/running/xsltscript and you try to include more than one of these scripts you'll notice that Saxon-CE only run the first script.

The presentation I'll be doing at "XML Asmterdam":http://xmlamsterdam.com/2013/sessions#forms (just after Mike ;) this coming Wednesday will be powered by Saxon-CE and I have used a first transformation (called boot-saxon.xsl) to read all these script elements and run the corresponding transformations.

The benefit is, as you say, to separate different features in different transformations (after all, this is something which is done for most JavaScript applications) and I find it most convenient.

In my boot-saxon.xsl I have added other features such as dymanic transformations (transformations generated dynamically from the source page) and it still remains relatively simple:





    
    
    

    
    
    

    
        
        
        
            
                
            
            
        
    

    
        
        
        
        
        
        
        
        
        
    

    
    
        
        
        
        
        
        
        
        
        
        
    



If you want to have a closer look, the code is available at https://gitlab.dyomedea.com/public/projects/presentations/xmlamsterdam2013. If you have a warning when cloning the repo you need to either install the intermediate certificate for my provider (http://wiki.gandi.net/en/ssl/intermediate) or (temporarily) switch SSL verification off:

$ GIT_SSL_NO_VERIFY=1 git clone https://gitlab.dyomedea.com/presentations/xmlamsterdam2013.git
Cloning into 'xmlamsterdam2013'...
remote: Counting objects: 982, done.
remote: Compressing objects: 100% (594/594), done.
remote: Total 982 (delta 407), reused 950 (delta 384)
Receiving objects: 100% (982/982), 5.52 MiB | 3.89 MiB/s, done.
Resolving deltas: 100% (407/407), done.

Please bear with me and note that the code would deserved to be cleaned up (this is my first application using Saxon-CE) and documented (I'll try to post a video after the conference)!

Hope this helps,

Eric

    (1-2/2)

    Please register to reply