Goals 
            
              Re-evaluate: what can XSLT  do now that’s
              in the pipeline space? How does it compare in difficulty?
            
            
              
                 
            
           
          
            Oil the Machine 
            
            
            Intro: here to talk about techniques that can make production workflow
            go more smoothly, not to re-implement XProc.
             
           
         
        
          Run XSLT 
          
            fn:transform() inspired this talk. 
            You can invoke another stylesheet from within XSLT . 
            The result is returned in a map. 
            fn:transform() changes the scope of XSLT. 
            Now you can use XSLT to coordinate groups of external transformations. 
           
         
        
          
            Why XSLT ? 
            
              An XSLT-only consulting client needed EPUB3 generation; 
              Fewer tools, processes, languages, technologies. 
             
            
              
                 
            
           
          
            Become the Machine 
            Gears © Animale38 by permission 
           
        
        
          Areas 
          
            Run XSLT  (obvious, but…) 
            Validation… 
            Queries… 
            External processes… 
            Zip, EPUB , EXP ath 
            Reading/writing 
            Inclusions, Exclusions, Conclusions 
           
         
        
          Validation 
          
            There’s no version of fn:document() that has options like whether to
            do DTD  validation, Schema validation, Schematron, etc.,
            but some XSLT  engines may have extensions or options for this.
          
         
        
          Queries 
          
            There’s no fn:query() in XSLT as standard, although there’s saxon:query().
            p:query is also an optional step in XProc.
          
         
        
          
            External Commands 
            Again optional in XProc.
            
              
                 
            
           
          
          XSLT that runs Perl 
            <xsl:message xmlns:system="java:java.lang.Runtime?void=this">
      <xsl:value-of select=" (
        system:exec(system:getRuntime(), '/bin/perl -f /tmp/insecure.pl', ()),
        ''
      )[2] " />
    
    <xsl:value-of select="doc('/tmp/out.xml')//text()" /> 
         
        
          
            Zip, EPUB , EXP ath 
            
              Read/write binary content and process Zip-format archives with
              the EXP ath file:read(), file:write() and archive:*()
              functions.
           
            
              Updating a ZIP archive 
              <xsl:variable name="archive" as="xs:base64Binary"
  select="archive:update(
    $emptyarchive,
    $alternatingvalues[(position() mod 2) eq 1],
    $alternatingvalues[(position() mod 2) eq 0]
) " />
<xsl:value-of select="( file:create-dir($dirname),
                           file:write-binary($outputfilename, $archive) )[1] "/> 
         
        
          Writing Restriction 
          
            XSLT 2 introduced xsl:result-document 
            Can’t read from a URL  you’ve written to. 
            fn:transform() returns a map containing not-actually-written documents,
            and also can call a function for each resource. 
           
         
        
          Mitigation of Restriction 
          
            The restriction doesn’t aply to file:read(), file:write(),
            file:write(fn:serialize($node)) etc. 
            You can “catch” the documents written by a called stylesheet
            and write them out with file:write(). 
           
          
            
              If we could override the entity resolver from within XSLT we could
              arrange not to write files out at all but return in-memory copes for
              the doc function.
            
           
         
        
          
            Strategy 
            
              Replace each XProc step with an XSLT function; 
              Sequence replaced by nested function calls: 
             
            step1 → step2 → step3can be rewritten as:
             step3( step2( step1() ) ) 
         
        
          
            Complications 
            
              Conditional operations and variables; 
              Catching written resources; 
              Multiple copies and flows. 
             
            
              
                 
            
           
          
            The Wider Context 
            
 
         
        
          Is it a good idea? 
          
            Performance 
            Memory and Streaming 
            Contorted plumbing 
            Awesomeness of Saxon 
            Relation to EXPath Tasks
            
         
        
          Questions