axis step child::processing-instruction(xml-stylesheet) 的上下文项未定义

The context item for axis step child::processing-instruction(xml-stylesheet) is undefined

我跟着 apply one xslt stylesheet recursively to sub-folders 获得了一个用 XSLT 2.0 递归转换的文件夹。 不幸的是,XSL 中的其他一些代码在这里出现问题,此时我真的无法理解:

$ 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

我的 XSL 文件是:

...
 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 生成一个相对路径,web 资源稍后将在该路径中,以便例如 css 可以正确加载。

我需要做什么才能让它正常工作?

PS: 运行 它在 saxonb-xslt -s:sourcefolder/ -xsl:clonk.xsl -o:targetfolder/ 之前工作正常但不是递归的。

如果您 运行 和 -it:main 没有上下文项,所以您不能指望使用全局变量或参数表达式能够 select 任何节点。您将需要重新组织您的代码,或许设置一个隧道参数,例如

 <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>

然后,在您需要参数的任何匹配模板中,您可以设置例如

<xsl:template match="foo">
  <xsl:param name="relpath" tunnel="yes"/>