0

i followed apply one xslt stylesheet recursively to sub-folders to get a folder recursively transformed with XSLT 2.0. Unfortunally some other code in the XSL make problems here and i am really out of my depth at this point:

$ saxonb-xslt -it:main -xsl:clonk.xsl -ext:on

Error on line 16 of clonk.xsl:
  XPDY0002: The context item for axis step child::processing-instruction(xml-stylesheet) is undefined
  in variable procinst (file:/mnt/.../clonk.xsl#16)
  at xsl:call-template name="head" (file:/mnt/.../clonk.xsl#78)
  in built-in template rule
  at xsl:apply-templates (file:/mnt/.../clonk.xsl#11)
     processing /
  at xsl:for-each (file:/mnt/.../clonk.xsl#9)
     processing /
Transformation failed: Run-time errors were reported

My XSL file is:

...
 8  <xsl:template name="main">
 9      <xsl:for-each select="collection('./sdk/?select=*.xml;recurse=yes')">
10          <xsl:result-document href="out/{tokenize(document-uri(.), '/')[last()]}">
11              <xsl:apply-templates select="."/>
12          </xsl:result-document>
13      </xsl:for-each>
14  </xsl:template>
15
16  <xsl:variable name="procinst" select="processing-instruction('xml-stylesheet')"/>
17  <xsl:param name="relpath" select="substring-after(substring-before($procinst, 'clonk.xsl'),'href=&quot;')"/>
...
76  <xsl:template match="/clonkDoc">
77      <html>
78          <xsl:call-template name="head"/>
79          <body>
...

relpath generates a relative path where the webresources will be later so that for example css can be loaded correctly.

What have i need to do to get this working?

PS: running it before with saxonb-xslt -s:sourcefolder/ -xsl:clonk.xsl -o:targetfolder/ worked fine but not recursive.

itsfoobar
  • 29
  • 6

1 Answers1

0

There is no context item if you run with -it:main so you can't expect to use global variable or parameter expression to be able to select any nodes. You will need to reorganize your code, perhaps set up a tunnel parameter e.g.

 <xsl:template name="main">
      <xsl:for-each select="collection('./sdk/?select=*.xml;recurse=yes')">
         <xsl:variable name="procinst" select="processing-instruction('xml-stylesheet')"/>
         <xsl:variable name="relpath" select="substring-after(substring-before($procinst, 'clonk.xsl'),'href=&quot;')"/>
         <xsl:result-document href="out/{tokenize(document-uri(.), '/')[last()]}">
             <xsl:apply-templates select=".">
               <xsl:with-param name="relpath" select="$relpath" tunnel="yes"/>
             </xsl:apply-templates>
         </xsl:result-document>
     </xsl:for-each>
 </xsl:template>

then, in any matching template where you need the parameter you can set up e.g.

<xsl:template match="foo">
  <xsl:param name="relpath" tunnel="yes"/>
Martin Honnen
  • 160,499
  • 6
  • 90
  • 110
  • Thank you, that worked fine! I thought it would have the context by passing the whole xml element in the colllection to the other templates that are applied on the xml. – itsfoobar Mar 10 '22 at 21:54
  • 1
    A slight caveat, if you supply both `-it:main` and `-s:some.xml` then there will be a context item available for global variables, but that's not useful when processing a collection, since global variables have the same value throughout a transformation. – Michael Kay Mar 11 '22 at 08:34