Java 与xsltproc相比,xsl:apply templates/xsl:with param与Xalan-J和saxon的异常行为

Java 与xsltproc相比,xsl:apply templates/xsl:with param与Xalan-J和saxon的异常行为,java,xslt,xslt-1.0,saxon,xalan,Java,Xslt,Xslt 1.0,Saxon,Xalan,我正在努力学习如何从java代码中使用XSLT1.0,但随着时间的推移,我开始一点一点地慢慢放松自己 我在我的类路径上有Xalan-J(Xalan.jar和xsltc.jar以及所有依赖项jar)、saxon和jing(后两者在我的项目中的其他地方使用),我使用JAXP结合System.setProperty调用强制使用类实现,如我想要的TransformerFactory。这还使我能够通过简单地更改代码中的属性来查看使用单个XSL转换文件的不同XSLT处理器的行为。此外,我还使用cygwin环

我正在努力学习如何从java代码中使用XSLT1.0,但随着时间的推移,我开始一点一点地慢慢放松自己

我在我的类路径上有Xalan-J(Xalan.jar和xsltc.jar以及所有依赖项jar)、saxon和jing(后两者在我的项目中的其他地方使用),我使用JAXP结合System.setProperty调用强制使用类实现,如我想要的TransformerFactory。这还使我能够通过简单地更改代码中的属性来查看使用单个XSL转换文件的不同XSLT处理器的行为。此外,我还使用cygwin环境中的xsltproc来查看它的功能。我还使用氧气进行调试,以确保我的java代码没有问题

看看这个虚拟XSL:


初始值:
最终值:
它除了调用一些在这个虚拟XML实例文档上工作的模板外,什么也不做:


我不知道我做错了什么,但是在XSL中传递唯一变量的值只适用于xsltc和xsltproc。普通xalan和saxon都无法传递该值。见下面的结果

xsltproc:

$ xsltproc transformation.xsl instance.xml
initial value: any-string-value
final value: any-string-value
Xalan编译处理器(xsltc和java 1.6默认实现):

Xalan解释处理器(Xalan):

撒克逊人:

Implementation: com.icl.saxon.TransformerFactoryImpl loaded from: ./lib/saxon6-5-5/saxon.jar
initial value: any-string-value
final value:

我需要这个与xalan一起工作(原因是可以接受EXSLT支持)。我不知道不同输出的原因可能是什么。我认为所有这些处理器都实现XSLT1.0,但我猜它们的实现方式不同。我在XSL中尝试做的事情是否与XSLT1.0不兼容?有没有一种解决办法可以让这一切顺利进行?

解释很简单:


最终值:
rng:optional
ex:data
的子项

ex:data
中没有模板匹配,因此它由元素节点的XSLT内置模板处理

当然,内置模板对传递给它的参数一无所知,因此它不会将这些参数传递给它应用的下一个模板

因此,XSLT内置的元素模板选择了匹配
rng:optional
(以上)的模板来执行,并且没有参数被传递给这个选择的模板


因此,
参数
param的值是空字符串,您可以从Saxon和XalanJ获得正确的输出。

这实际上是有意义的。似乎xsltproc和xsltc内置模板处理参数,即使它们不应该…将一个您认为是可移植的XSL转换成完全相反的形式。@predi:因此,解决方案是使用一个匹配
ex:data
的模板,该模板声明了参数,并将通过其
XSL:apply templates
yes传递参数。如果添加缺少的模板,则该参数将具有预期的值(在该模板内)。然后,它必须通过起点和目标之间的整个“路径”进行适当的授权,即使中间的部分对您来说是无用的。如果使用参数,则使用子代轴或类似的东西进行切割是不允许的。在XSLT 2.0和2.0+中,可以使用称为“隧道参数”的功能。
Implementation: org.apache.xalan.processor.TransformerFactoryImpl loaded from: ./lib/xalan-j_2_7_1/xalan.jar
initial value: any-string-value
final value:
Implementation: com.icl.saxon.TransformerFactoryImpl loaded from: ./lib/saxon6-5-5/saxon.jar
initial value: any-string-value
final value:
  <xsl:template match="rng:optional">
    <!-- use the param value here -->
    <xsl:param name="parameter"/>
    <xsl:message>final value: <xsl:value-of select="$parameter"/></xsl:message>
  </xsl:template>